TypeScript索引属性不匹配推断的泛型类型



这段代码编译失败:

type Validator<T> = (value: string) => { value: T }
const createValidator = <TState extends any>(state: TState) =>
<TName extends keyof TState>(x: TName, validator: Validator<TState[TName]>) => {
return (value: { [P in TName]: string }): { [P in TName]: TState[TName] } => {
const result = validator(value[x]);
return { [x]: result.value };
};
}

return { [x]: result.value };给我Type '{ [x: string]: TState[TName]; }' is not assignable to type '{ [P in TName]: TState[TName]; }'.,即使TName是从x推断出来的。

为什么?除了转换返回值之外,我还能做些什么呢?

这里的问题是,TypeScript不会在具有计算属性的对象字面量中推断索引签名。最简单的例子:

type KEY = 'foo' | 'bar';
let obj = { ['foo' as KEY]: 1 };
// obj is of type: { [x: string ]: number }
// and NOT the { foo: number, bar: number }
// and NOT the Record<'foo'|'bar', number>

所以在你的例子中,你应该强制转换,为了使它更简单,重用变量的类型,而不是重复:

return { [x]: result.value } as Record<typeof x, typeof result.value>;

最新更新