简体   繁体   English

基于泛型接口推断参数和返回类型

[英]Infer params and return types based on generic interface

I am building a function which accepts an interface and I want this to infer the return types from the 'key' in my options object passed as a function param我正在构建一个接受接口的 function 并且我希望它从作为 function 参数传递的选项 object 中的“键”推断返回类型

My desired results would be something like this reduced code example:我想要的结果将类似于这个简化的代码示例:

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 


But with my current code the key type is 'a' | 'b'但是使用我当前的代码, key类型是'a' | 'b' 'a' | 'b' and the value type is 'string' | 'number' 'a' | 'b'和值类型是'string' | 'number' 'string' | 'number' . 'string' | 'number'

My current broken solution is:我目前的解决方案是:

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,
  });

I have tried to create a type for KeyValue which includes the options inside a function and type the returns but the completely breaks the mapping.我试图为KeyValue创建一个类型,其中包括 function 中的选项并键入返回,但完全破坏了映射。

Fuller example is in this Link to Playground更完整的示例在此指向 Playground 的链接中

Currently, the key property is not generic.目前, key属性不是通用的。 The function does not know or care which value you pass to it. function 不知道也不关心您传递给它的值。 The output type can therefore not change based on the key .因此 output 类型不能根据key进行更改。


The "easy" solution would be to add a generic type for key . “简单”的解决方案是为key添加泛型类型。

const createKeyValueMapped = <
  Inputs, 
  K extends keyof Inputs
>({ key, value }: KeyValue<Inputs, K>) =>
  ({
    key,
    value,
  });

The caller would have to specify the key explicitly when calling the function since TypeScript does not support partial type inference yet.调用者在调用 function 时必须明确指定键,因为TypeScript 还不支持部分类型推断

const stringKeyValue = createKeyValueMapped<CustomInputs, "a">({
  key: "a",
  value: "hi",
  transform: (value) => value + ' more text',
});

If we want to avoid explicitly setting the second generic type, we can use currying.如果我们想避免显式设置第二个泛型类型,我们可以使用柯里化。

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',
});

The outer function takes an explicit generic type while the inner function infers the key .外部 function 采用显式泛型类型,而内部 function 推断key

stringKeyValue.key; // "a"
stringKeyValue.value; // string

Playground 操场

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM