[英]Infer params and return types based on generic interface
我正在构建一个接受接口的 function 并且我希望它从作为 function 参数传递的选项 object 中的“键”推断返回类型
我想要的结果将类似于这个简化的代码示例:
const stringKeyValue = createKeyValueMapped<{a: string, b: number}>({
key: "a", // key: "a"
value: "hi", // value: string
transform: (value) => value + ' more text', // (value: string) => string
});
stringKeyValue.key; // key: 'a'
stringKeyValue.value; // value: string
但是使用我当前的代码, key
类型是'a' | 'b'
'a' | 'b'
和值类型是'string' | 'number'
'string' | 'number'
。
我目前的解决方案是:
export type KeyValue<
Inputs,
Key extends keyof Inputs,
Value = Inputs[Key]
> = {
key: Key;
value: Value;
transform: (value: Value) => Value;
};
type KeyValuesMapped<Inputs> = {
[Key in keyof Inputs]: KeyValue<Inputs, Key>;
}[keyof Inputs];
const createKeyValueMapped = <Inputs,>({ key, value }: KeyValuesMapped<Inputs>) =>
({
key,
value,
});
我试图为KeyValue
创建一个类型,其中包括 function 中的选项并键入返回,但完全破坏了映射。
更完整的示例在此指向 Playground 的链接中
目前, key
属性不是通用的。 function 不知道也不关心您传递给它的值。 因此 output 类型不能根据key
进行更改。
“简单”的解决方案是为key
添加泛型类型。
const createKeyValueMapped = <
Inputs,
K extends keyof Inputs
>({ key, value }: KeyValue<Inputs, K>) =>
({
key,
value,
});
调用者在调用 function 时必须明确指定键,因为TypeScript 还不支持部分类型推断。
const stringKeyValue = createKeyValueMapped<CustomInputs, "a">({
key: "a",
value: "hi",
transform: (value) => value + ' more text',
});
如果我们想避免显式设置第二个泛型类型,我们可以使用柯里化。
const createKeyValueMapped = <Inputs,>() =>
<K extends keyof Inputs>({key, value}: KeyValue<Inputs, K>) => ({
key,
value,
});
const stringKeyValue = createKeyValueMapped<CustomInputs>()({
key: "a",
value: "hi",
transform: (value) => value + ' more text',
});
外部 function 采用显式泛型类型,而内部 function 推断key
。
stringKeyValue.key; // "a"
stringKeyValue.value; // string
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.