typescript - Typescript keyof T 类型断言与类型注释
问题描述
我试图了解这是类型断言的预期工作机制还是编译器错误。
这是用例:
interface IExample {
one: string;
two: number;
}
interface IGeneric<T> {
example: [key: keyof T, someText: string][]; // tuple array
}
这些是 3 个示例及其各自的错误消息。1 和 2 似乎按预期工作,但令我惊讶的是 example3 的行为与 example1 不同?
// Type '"three"' is not assignable to type 'keyof IExample'.(2322)
let example1: IGeneric<IExample> = { example: [
['one', 'one'],
['three', 'three'],
]};
/*
Conversion of type '{ example: (["three", string] | ["four", string])[]; }' to type 'IGeneric<IExample>' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
Types of property 'example' are incompatible.
Type '(["three", string] | ["four", string])[]' is not comparable to type '[key: keyof IExample, someText: string][]'.
Type '["three", string] | ["four", string]' is not comparable to type '[key: keyof IExample, someText: string]'.
Type '["four", string]' is not comparable to type '[key: keyof IExample, someText: string]'.
Type at position 0 in source is not compatible with type at position 0 in target.
Type '"four"' is not comparable to type 'keyof IExample'.
*/
let example2 = { example: [
['three', 'three'],
['four', 'four'],
]} as IGeneric<IExample>;
// no error ??
let example3 = { example: [
['one', 'one'],
['three', 'three'],
]} as IGeneric<IExample>;
解决方案
您应该将其as
视为一种抑制类型错误的方法;当您比编译器更清楚某事物的类型时,或者当您为了方便而想对编译器撒谎时,您可以使用它。因此,当您as
在第三个示例中使用时没有出现类型错误并不奇怪;这as
就是应该做的。
真正的问题是为什么您的第二个示例确实给出了类型错误。本质上,这是因为在您的第三个示例中,推断类型与断言类型有一些重叠,而在您的第二个示例中,与断言类型没有重叠。该as
关键字旨在告诉编译器一种类型的值实际上是不同的类型,但如果这两种类型根本没有重叠,那么编译器仍然会给出错误,因为你断言的不仅仅是假,这在逻辑上是不可能的。*
* 学究式注意:从技术上讲,这两种类型根本不完全没有重叠,因为具有空数组的对象{example: []}
可以分配给这两种类型。尽管如此,同样的理由也适用。如果类型有足够的重叠,编译器愿意“相信你的话”,但如果重叠太小以至于你可能犯了错误,它仍然会出错。
推荐阅读
- python - 在 Django 中序列化关系
- android - 如何使用jetpack compose将按钮标记为可选
- android - 由于在应用程序安装期间超时而无法运行排毒测试
- hibernate - 休眠查询:通过映射键加入
- android - 以预定的时间间隔在本机反应中调用休息 API
- java - 用于逐步添加字符串填充的循环?
- c# - CS0122:“AmazonGlacierClient.ListVaults()”因其保护级别而无法访问
- swift - 将 SwiftUI 2.0 应用程序连接到 Firebase 时出错
- hash - 具有自适应哈希函数的哈希表
- kubernetes - 你能解决 Kubernetes 中的 1 个 pod/node/container 1 负载均衡器吗?