keyof result包含'未定义'当用于从具有可选键的对象映射的对象时



这怎么可能?AFAIKundefined不能用作对象密钥。并且FooOptionalNumber不包含这样的密钥。它是从哪里来的?TS是否在某些条件下将undefined添加到对象?

type PickByValue<T, ValueType> = Pick<T, {
[Key in keyof T]: T[Key] extends ValueType ? Key : never;
}[keyof T]>;
interface Foo {
user: string
age?: number
score?: number    
}
//'user' | 'age' | 'score' - as expected
type FooKeys = keyof Foo
// as exptected
// { 
//     age?: number | undefined
//     score?: number | undefined
// }
type FooOptionalNumber = PickByValue<Foo, number | undefined>
// 'age' | 'score' | undefined - Where did the 'undefined' come from??
type FooOptionalNumberKeys = keyof FooOptionalNumber

游乐场链接

Typescript专家答案在这里。这个定义

type PickByValue<T, ValueType> = Pick<T, {
[Key in keyof T]: T[Key] extends ValueType ? Key : never;
}[keyof T]>; 

是无效的,实际上应该会产生编译错误(但事实并非如此(。这是因为类型never的可选属性实际上变成了undefined:

type SpecialUndefined = { foo?: never } //actually it is: { foo?: undefined }

所以这个表达式{ [Key in keyof T]: T[Key] extends ValueType ? Key : never;}使得不扩展ValueType的可选值为undefined而不是never。因此,我们传递给Pick作为第二个参数的并集包含undefined-Pick<User, "foo" | undefined>。将keyof应用于此类型只会拉出所提供的密钥"foo" | undefined,尽管这是一个非法类型。

最新更新