这真让我抓狂。
我有这个自定义类型:
export default interface Folder {
name: string;
reports: Array<Report>;
}
我想构建一个存储在以下位置的文件夹数组:
reportsDashboard: [] as Folder[]
我检索文件夹中的报告列表。Report
我有文件夹名称和要迭代的报告类型列表。
export default interface Report {
datasetId: string;
datasetWorkspaceId: string;
embedUrl: string;
id: string;
isFromPbix: boolean;
isOwnedByMe: boolean;
name: string;
reportType: string;
subscriptions: Array<any>;
users: Array<any>;
webUrl: string;
folder: string | undefined;
}
首先,我需要声明一个变量来填充我的文件夹,然后我想将其推入我的reportsDashboard
数组中。
并且folderName是一个字符串| 不明确的:
const folderName: string | undefined = reportsStore.reportWorkspaceMap.find((w) => w.role === roles[role])?.folder;
这是引导我来到这里的尝试......
// This is what the AI tried to tell me would work HA!
let folder: Folder | null = null;
folder.name = folderName;
for (const report in incomingReports) {
folder.reports.push(r);
}
当我添加 | 时,这就是现在正在工作的内容。我的文件夹类型中的 name 属性未定义
// I started with this somewhat, but I guess the undefined threw me off, thanks @Phil
let folder: Folder = { name: folderName, reports: [] };
folder.name = folderName;
for (const report in incomingReports) {
folder.reports.push(r);
}
设置folder
为 null 后,我收到了 IDE 和控制台消息:
// IDE: "'folder' is possibly 'null'"
// Console: "TypeError: Cannot set properties of null (setting 'name')"
如果不设置folder
为 null,我会收到 IDE 和控制台消息:
// IDE: "Type 'string | undefined' is not assignable to type 'string'.
// Type 'undefined' is not assignable to type 'string'."
// Console: "TypeError: Cannot set properties of undefined (setting 'name')"
我找不到一个简单的例子,所以我尝试了 Open AI,它在过去是有效的。我什至问它如何处理这些特定的错误,并且在我问它的所有方式中,它都说将其设置为 null 应该告诉 TypeScript“这是预期的,没关系”......但没有。
最重要的是,在第二个示例中,当我尝试将报告推入数组时,我得到了这个(并且仍然如此,但它有效):
Argument of type 'import("c:/Projects/Project/types/Report").default' is not assignable to parameter of type 'Report'.
Type 'Report' is missing the following properties from type 'Report': body, type, url, toJSON
编辑1
在这里我认为这是显而易见的哈哈哈
在 JavaScript 中,我会(为了简洁起见,因为在我的实际应用程序中,有几个 API 调用从 Power BI 等获取内容):
const workspaces = [
{
name: "Workspace 1",
id: "some guid"
},
{
name: "Workspace 2",
id: "some guid"
},
]
const incomingReports = [
{
name: "Report 1",
url: "Url"
},
{
name: "Report 2",
url: "Url"
},
]
for (const workspace in workspaces) {
const folderName = workspace.name
// fetch reports for workspace resulting in incomingReports
let folder = { name: folderName, reports: []}
for (const r in incomingReports) {
folder.reports.push(r)
}
}
应该将一组文件夹对象放入另一个数组中,其中文件夹对象如下所示:
{
name: "Workspace 1",
reports: [
{
name: "Report 1",
url: "Url"
},
{
name: "Report 2",
url: "Url"
},
]
}
我坚持填充文件夹类型的变量就是全部。
我想我不明白如何创建一个类型的变量,然后给它赋值,而 TS 不告诉我它没有值。显然,这是显而易见的,尤其是。使用上面建议的代码,但我很绝望,哈哈。
我发现的所有学习这一点的例子要么太简单,要么太复杂,或者对“当时我正在观看或阅读的人”有效。
编辑2
当我不指定类型时:
r 是Argument of type 'Report' is not assignable to parameter of type 'never'.
当我指定类型时:
名字是Type 'string | undefined' is not assignable to type 'string'.
r 是Type 'Report' is missing the following properties from type 'Report': body, type, url,
等
编辑3
所以我让它工作了,有点。
将文件夹类型更新为(添加| undefined
),感觉很脏:
export default interface Folder {
name: string | undefined;
reports: Array<Report>;
}
但 r 变量仍在大喊大叫,但数据按预期填充。我想这就是我现在定义报告数组的方式。
我之前尝试更新 Name 类型以包含未定义的内容,但我认为我的代码略有不同,因此 TS 警告我有其他情况。哦。
这些错误消息告诉您出了什么问题。
这里你说的
folder
是类型的变量Folder
,或者它是一个null
对象。然后你将它设置为一个
null
对象。这是允许的,因为类型匹配。空对象没有属性。因此,当您键入时,
folder.name
您可能正在访问一个没有属性的对象。Typescript 指出了这个错误。解决此问题的最简单方法是不创建
folder
空对象。当您尝试修复此问题时,您会收到以下错误:
现在你试图通过隐藏价值类型来让人们难以解决这个问题
folderName
。对您来说不幸的是,类型脚本错误非常清楚地解释了您的问题。它表明您正在尝试将某种类型分配
string | null
给类型的变量string
。Typescript 说你不能这样做: a
name
是一个字符串并保证为非 null。同时右侧的值明确指出它可以为空。所以打字稿会给你一个错误。
语言中的类型将运行时错误转移到编译时。逻辑错误——当你承诺它永远不会时,字符串可能最终为空——成为打字稿中的编译时错误,而在 JavaScript 中,你必须在运行时捕获它。
或者,更现实的是,您无法捕获它,您将发送代码,当 1 个月后开始获得空输入时,它会崩溃千分之一,并且每次崩溃都会破坏平均价值 10 美元的交易。以每小时 100 万笔交易计算,并且需要 5 个小时来查找、修复、验证和部署修复,这使公司损失了 50,000 美元的收入。
这就是为什么他们让你使用打字稿,这样你就可以在编译时修复这个错误,而不是发布有错误的代码。
要理解打字稿,您需要了解总和和乘积类型(或并集和交集)。 https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#union-types是文档来源之一。
最简单的就是
null
folderName
然后写下如果传入a 应该如何处理。设置folder.name = 'i am a chicken'
?任何你想要的。