鉴于我有这样的类型:
type Foo = {
foo: number;
bar: string;
baz: boolean;
}
我想要一个类型 Buzz
,它可以检测键的值类型,即
const abc: Buzz<Foo> = {
key: 'foo',
formatter: (detectMe) => {} //I want TS to infer this to be 'number'
};
给定键“foo”,格式化程序中的参数应该被推断为number
。我试过这个:
interface ColumnDescription<T> {
label: string;
key: keyof T;
formatter?: (datum: T[keyof T]) => void;
}
然而,这会导致参数被推断为 number |字符串| bool 值
.
也尝试过这个:
interface ColumnDescription<T, K extends keyof T> {
label: string;
key: K;
formatter?: (datum: T[K]) => void;
}
这种方法可行,但我总是需要在第二个类型参数中指定键,而不是自动发生。即:
const abc: Buzz<Foo, 'foo'> = { //I don't want to specify the key
key: 'foo',
formatter: (detectMe) => {} //This is inferred correctly
};
最佳答案
就像我的评论一样,我建议
type Buzz<T> = {
[K in keyof T]-?: { key: K; formatter: (d: T[K]) => void }
}[keyof T];
这与您对 Buzz<T, K extends keyof T>
所做的类似,而不是制作 Buzz
需要 K
需要说明的是,我使用了 mapped type {[K in keyof T]: ...}
它会自动迭代 keyof T
中的键并使用相同的键创建一个新对象,但其属性值是您要查找的类型。这意味着获得所需的 Buzz<T>
我们需要look up属性值,通过使用 [keyof T]
对其进行索引。这使得Buzz<T>
类型的联合,其中联合的每个组成部分对应于您的 Buzz<T, K extends keyof T>
对于特定键K
让我们确保它有效:
const abc: Buzz<Foo> = {
key: "foo",
formatter: detectMe => {} // inferred as number, as desired
};
看起来不错,让我们检查一下 abc
的类型使用智能感知:
const abc: {
key: "foo";
formatter: (d: number) => void;
} | {
key: "bar";
formatter: (d: string) => void;
} | {
key: "baz";
formatter: (d: boolean) => void;
}
看起来也不错。
好的,希望有帮助;祝你好运!
关于Typescript - 根据提供的对象键检测值类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56828431/