我有一个用于属性集合的类型/接口。
每个属性都有自己指定的类型。请参见下面的代码示例中的Props
。
我正在尝试定义一个元组<A, B>
的类型,其中A
必须是其中一个属性的名称,而B
必须是该属性的对应类型。该属性的值。
例如,['someStr', 'a']
应该满足类型,而['someStr', 1]
应该失败,因为根据Props
1
必须是字符串。
下面是一些实验代码:
interface Props {
someStr: string;
someNum: number;
}
type FuncWithPropInput = <T extends keyof Props>(key: T, value: Props[T]) => [typeof key, typeof value];
// I don't have to specify `T` as it's inferred from `key`.
const workWithProps: FuncWithPropInput = (key, value) => [key, value];
workWithProps('someStr', 'a'); // No error, as expected.
workWithProps('someStr', 5); // Error about `5` not a string, as expected.
workWithProps('foobar', 5); // Error about `'foobar'` not in collection, as expected.
type TupleWithPropKeyAndValue<T extends keyof Props> = [
T,
Props[T]
];
// Unexpected: it complains about missing type argument `T`.
const var1: TupleWithPropKeyAndValue = [
'someStr',
5 // Unexpected: No error here.
];
const var2: TupleWithPropKeyAndValue<'someStr'> = [
'someStr',
5 // Error about `5` not a string, as expected.
];
const var3: ReturnType<FuncWithPropInput> = [
'someStr',
5 // Unexpected: No error here.
];
我的困惑是上面的示例中的FuncWithPropInput
有效,但是TupleWithPropKeyAndValue
不起作用。
我希望能够编写类似var1
的情况,并让TypeScript抛出有关5
的错误,该错误必须是字符串。
此外,由于FuncWithPropInput
可以正常工作,所以我很困惑地看到var3
失败的情况。
答案 0 :(得分:0)
变量的类型推断是全有或全无。根据初始化表达式推断类型,或者由类型注释设置类型,并且不进行推断。没有var1
所需要的部分推断,您可以在其中指定泛型类型,而Typescript会填空。
解决此问题的常用方法是您已经找到的一种方法。使用函数来推断受某种方式约束的类型参数。
ReturnType
不执行您期望的原因是Typescript只会将可能使用的最大类型用作type参数,并返回返回类型,因为不会发生其他魔术。