gpt4 book ai didi

typescript - 类型 'undefined' 不可分配给类型 'never'

转载 作者:行者123 更新时间:2023-12-03 23:10:02 27 4
gpt4 key购买 nike

interface A {
name?: string
age: number
}

var a: A = {
name: '',
age: 23
}

var result:A = (Object.keys(a) as Array<keyof A>).reduce((prev, key) => {
if (a[key] || a[key] === 0) {
prev[key] = a[key] // this reported a error about `Type 'undefined' is not assignable to type 'never'`
}
return prev
}, {} as A)

console.log(JSON.stringify(result))

以上是重现代码。

我发现该代码在typescript@~3.4.0下有效,但在typescript@^3.5.0下无法编译,我检查了3.4和3.5之间的更新日志,但没有找到任何关于此的引用。

所以我猜是不是因为 index signature未设置,则:
interface A {
name?: string
age: number
[K:string]:any <-- add this line
}

var a: A = {
name: '',
age: 23
}

var result:A = (Object.keys(a) as Array<keyof A>).reduce((prev, key/* validation lost */) => {
if (a[key] || a[key] === 0) {
prev[key] = a[key]
}
return prev
}, {} as A)

console.log(JSON.stringify(result))

之前的错误消失了,但是 key的类型那是 reduce 中的参数回调变成了 string|number ,导致 key 的类型验证丢失。

这是正常行为吗?

如果是,我想知道如何解决 Type 'undefined' is not assignable to type 'never' ,并保持对 key 的类型检查.

最佳答案

在 TS 3.5 中,PR Improve soundness of indexed access types 实际上发生了重大变化:

When an indexed access T[K] occurs on the source side of a type relationship, it resolves to a union type of the properties selected by T[K], but when it occurs on the target side of a type relationship, it now resolves to an intersection type of the properties selected by T[K]. Previously, the target side would resolve to a union type as well, which is unsound.



继续到您的示例, prev[key] = a[key] 现在发出错误,因为 key 具有联合类型 "name" | "age" 并且 prev[key](赋值的目标端)解析为所有选定属性的交集类型: A["name"] & A["age"] ,即 string & number 或换句话说 never ( prev 类型为 A )。

这个 prev[key] 的推断交集背后的想法是确保 "name" | "age" 的所有可能的键 prev 都可以安全地写入。如果 key 的运行时值为 age ,则向其写入 string ( name 的预期属性类型)将是错误的。在 keyof A 类型的编译时,我们不知道 key 的确切值是什么,因此 PR 中的更改强制执行更安全的类型。

解决方案是为对象( prev )和/或属性名称( key )引入泛型类型参数。维护者给出了一些示例 hereherehere 。我不确定您的用例,但例如您可以像这样重写代码:
const result: A = (Object.keys(a) as Array<keyof A>).reduce(
<K extends keyof A>(prev: A, key: K) => {
// t[key] === 0 would only work for numbers
if (a[key] /* || t[key] === 0 */) {
prev[key] = a[key]
}
return prev
}, {} as A)

Playground

关于typescript - 类型 'undefined' 不可分配给类型 'never',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59173087/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com