我喜欢类型安全,这就是我喜欢打字稿的原因.
但是,我发现在最终必须明确声明额外变量以获得我需要的类型安全性的情况.
更新的例子:
假设我想在一个字符串数组上调用".join",我真的想确保它是一个字符串数组(而不是像对象那样最终输出为[object Object]):
如果我只是在这里执行此代码,它不会阻止我意外地传入一个对象somethingElse:
如果我为urlParts它创建一个数组并键入它string[],我可以防止这个问题:
const baseUrl = "https://stackoverflow.com/"
const somethingElse = { not: "a string" };
const urlParts: string[] = [baseUrl, somethingElse];
window.location.replace(urlParts.join("\n"))
Run Code Online (Sandbox Code Playgroud)
但是,如果没有创建一个urlParts我希望避免的单独变量,似乎没有办法让我这样做.例如,通过以下之一:
window.location.replace(([baseUrl, somethingElse] as string[]).join("\n"))
window.location.replace((<string[]>[baseUrl, somethingElse]).join("\n"))
Run Code Online (Sandbox Code Playgroud)
我发现避免创建变量的唯一方法是将结果内联为一个自执行的匿名强类型函数 - 但这似乎是一个荒谬的解决方法:
window.location.replace(((): string[] => [baseUrl, somethingElse])().join("\n"))
Run Code Online (Sandbox Code Playgroud)
这是一个TypeScript错误/差距吗?或者我错过了什么?
我问几位同事,看他们是否有任何想法,但我们无法弄清楚如何获得更严格的类型.
谢谢!
键入断言是小于安全类型的注释,因为同时兼具注释和断言允许你扩大的表达,这是阅读安全的类型,只有输入断言允许你缩小的表达,这是不安全的阅读类型.编译器允许您执行此操作,因为您声明它是真的.
举个例子......假设给你一个x类型的变量string.如果您只是读取该变量的值,则可以将变量视为更宽泛的类型string | number.这是因为类型的所有值string都还有类型的值string | number.因此,无论let y: string | number = x和x as string | number是有效的,因为编译器可以验证这些表达式的有效性.
另一方面,如果给出一个y类型的变量,将变量视为较窄的类型string | number是不安全的.这是因为有类型的值这是不是类型的值.所以会给编译错误; 编译器知道将a 视为a 是不安全的.但是被允许,因为你告诉编译器你知道的比它更多.有时,编译器会推断出比您更广泛的类型,如."很显然," 将是一个,但是编译器不会(为TS3.3)公告,只有三元运算符的真正分公司将进行评估,并因此推断的.所以你可以断言是安全的,编译器会相信你. stringstring | numberstringlet x: string = ystring | numberstringy as stringlet y = true ? "a" : 1;ystringstring | numberyy as string
此外,如评论中所述,术语"类型断言"优于"类型转换",通常因为"类型转换"有时意味着某些运行时效应.TypeScript的类型系统在运行时被完全擦除,因此只有在设计时类型系统才能执行任何操作.断言是你告诉编译器不要担心它是否无法验证特定表达式是否属于特定类型.如果你的断言是正确的,那么一切都很好.如果你的断言是不正确的,那么在设计时一切似乎都很好,那么你将收获任何运行后果.
类型断言并非完全不安全; x as T如果所推断的类型x既不比类型更窄也不宽,那么编译器仍然可能会断言断言T.例如,如果你有一个z类型的变量,string你编写z as number编译器仍然会警告你.在这种情况下,您仍然可以强制编译器提交,方法是在继续之前始终先扩展到常用的超类型或缩小到公共子类型.类型unknown是所有类型的commmon超类型,因此您始终可以编写z as unknown as number并静默编译器中的任何可能的异议.
另请注意,x as T类型断言的语法与语法完全相同<T> x.有两种写法的唯一原因是因为尖括号与JSX不能很好地配合.
好的,希望有所帮助; 祝好运!
更新:我认为以内联方式获得类型注释安全性的最简单方法是使用辅助函数.这并不像你正在使用的IIFE那么疯狂,但它是相似的.这是我如何做到的:
const ann = <T>(x: T) => x;
Run Code Online (Sandbox Code Playgroud)
该函数ann("annotate"的缩写)允许您显式注释传入参数的类型.让我们来看看:
window.location.replace(ann<string[]>([baseUrl, somethingElse]).join("\n"))
// error on somethingElse, as expected
Run Code Online (Sandbox Code Playgroud)
这对你有用吗?
| 归档时间: |
|
| 查看次数: |
66 次 |
| 最近记录: |