原始对象和扩展对象之间的 TypeScript 区别
TypeScript difference between original object and spreaded object
有个打字谜语我看不懂:
const randomFn = (arg: Record<string, unknown>): string => 'kappa'
export type Values = {
key: string;
};
const values: Values = {
key: 'kappa'
}
const { ...spread } = values;
randomFn(values)
randomFn(spread) // produce Index signature for type 'string' is missing in type '{ transaction: string; }'.(2345)
为什么 Typescript 会为传播对象产生错误,而据我所知,它的输入应该是相同的。
如果我们检查 playgroud 中的对象,它与 TS 编译器完全相同。原创和传播。
TS 版本 4.5.4。
在 Type Script Playground
中复制
编辑:还进行双重传播以使其再次工作。
randomFn({...spread}) // NO error
传播丢失类型,因为它不能保证传播对象的类型相同。考虑一下:
const { excluded, ...rest } = object;
显然rest
不能和object
是同一类型;缺少一把钥匙!
你也可以这样想:
const [excluded, ...rest] = array;
这就是为什么 spread
不是类型 Values
。
这是 TypeScript 设计限制的结果,请参阅 microsoft/TypeScript#42021 for details. When you use a rest element in an object destructuring assignment, TypeScript unfortunately does not copy an index signature into the type of the new variable. Nor does it allow the variable to have an implicit index signature (although I'm not sure why)。
你的 Values
类型别名允许有一个隐式索引签名(如果你把它设为 interface
那么它也不会,见 microsoft/TypeScript#15300),所以它是被认为可分配给 Record<string, unknown>
(相当于 {[k: string]: unknown}
,一种具有字符串索引签名的类型)。但是 spread
作为 rest-destructured 变量不是,因此它失败了。
您注意到进行第二次剩余解构 确实 起作用,所以大概有一些关于如何标记对象类型以允许或禁止隐式索引签名的奇怪之处。这也是 microsoft/TypeScript#42021 中的 noted,尽管没有解释。
所以很遗憾,目前还没有一个非常令人满意的答案,除非 microsoft/TypeScript#42021 中出现更多 activity。
有个打字谜语我看不懂:
const randomFn = (arg: Record<string, unknown>): string => 'kappa'
export type Values = {
key: string;
};
const values: Values = {
key: 'kappa'
}
const { ...spread } = values;
randomFn(values)
randomFn(spread) // produce Index signature for type 'string' is missing in type '{ transaction: string; }'.(2345)
为什么 Typescript 会为传播对象产生错误,而据我所知,它的输入应该是相同的。 如果我们检查 playgroud 中的对象,它与 TS 编译器完全相同。原创和传播。
TS 版本 4.5.4。 在 Type Script Playground
中复制编辑:还进行双重传播以使其再次工作。
randomFn({...spread}) // NO error
传播丢失类型,因为它不能保证传播对象的类型相同。考虑一下:
const { excluded, ...rest } = object;
显然rest
不能和object
是同一类型;缺少一把钥匙!
你也可以这样想:
const [excluded, ...rest] = array;
这就是为什么 spread
不是类型 Values
。
这是 TypeScript 设计限制的结果,请参阅 microsoft/TypeScript#42021 for details. When you use a rest element in an object destructuring assignment, TypeScript unfortunately does not copy an index signature into the type of the new variable. Nor does it allow the variable to have an implicit index signature (although I'm not sure why)。
你的 Values
类型别名允许有一个隐式索引签名(如果你把它设为 interface
那么它也不会,见 microsoft/TypeScript#15300),所以它是被认为可分配给 Record<string, unknown>
(相当于 {[k: string]: unknown}
,一种具有字符串索引签名的类型)。但是 spread
作为 rest-destructured 变量不是,因此它失败了。
您注意到进行第二次剩余解构 确实 起作用,所以大概有一些关于如何标记对象类型以允许或禁止隐式索引签名的奇怪之处。这也是 microsoft/TypeScript#42021 中的 noted,尽管没有解释。
所以很遗憾,目前还没有一个非常令人满意的答案,除非 microsoft/TypeScript#42021 中出现更多 activity。