繁体   English   中英

Typescript:- 使用 object 为 function 创建泛型类型,其中一个键作为值类型,返回类型是值

[英]Typescript :- create generic type for function taking object having one key as type of value and return type is value

我正在努力输入 function。 下面的代码段在此行中抛出错误export type DataAttributeType<T> = BACKEND_PRIMITIVE[T]

我想创建一个 function,它采用示例输入并返回示例 output。

示例 1:

input:- {"S": "2015-02-18T20:27:36.165Z"}
Output:- "2015-02-18T20:27:36.165Z"

示例 2:

input:- {"N": 10 }
Output:- 10

我试过的:

export const enum DATATYPE {
    S = "S",
    N = "N"
}

type BACKEND_PRIMITIVE = {
    [DATATYPE.S]: string;
    [DATATYPE.N]: number;
};

export type BackendDataAttributeType<T> = {
    [T in DATATYPE]?: BACKEND_PRIMITIVE[T];
};

export type DataAttributeType<T> = BACKEND_PRIMITIVE[T];

export const mapToPlainObject = <T>(
    attribute: BackendDataAttributeType<T>
): DataAttributeType<T> => {
    if (attribute.S) {
        return attribute.S;
    }
    if (attribute.N) {
        return attribute.N;
    }

    throw new Error("Not able to parse attribute");
};

问题是我无法保留与输入相同的返回类型。 如果键是 S 那么返回类型应该是一个字符串。

帮助将不胜感激

您应该定义允许的基本类型。 然后定义您的包装器属性 class。 然后定义一个 function 从包装器 class 返回基本类型。

包装和属性示例

    // The limited set of types for attributes
    type AlllowedAttributeType = string | number | { foo: string, bar: string};

    // Create a rich interface for you data type
    interface MyDataAttributeType<AlllowedAttributeType> {
      name: string;
      data: AlllowedAttributeType;
    }

    // Type of the function that returns the attribute value
    type GetAttributeValue = 
      (input: MyDataAttributeType<AlllowedAttributeType>) => AlllowedAttributeType;

    // Return just the value part
    const myGetTypedData: GetAttributeValue = (input) => {
      return input.data;
    };

用法

    const d1 = {
      name: 'data1',
      data: 1,
    }

    const d2 = {
      name: 'dataTwo',
      data: 'Two',
    }

    const d3 = {
      name: 'complex',
      data: { foo: 'biz', bar: 'baz' }
    }

    console.log(myGetTypedData(d1));
    console.log(myGetTypedData(d2));
    console.log(myGetTypedData(d3));

    const d4 = {
      name: 'error',
      data: { wrong: 'type' },
    }
    // wont compile
    console.log(myGetTypedData(d4));

我不是 100% 确定你想要做什么,但我的直觉是这样写mapToPlainObject

const mapToPlainObject = <T extends Partial<BACKEND_PRIMITIVE>>(
    attribute: T
): T[keyof T] => {
    return attribute[(Object.keys(attribute) as Array<keyof T>)[0]];
};

在这里,我是说您将传入具有BACKEND_PRIMITIVE的某些属性的东西(我想它总是恰好是一个这样的属性)并返回其中一个(如果恰好有一个,则返回那个)。 (请注意, Object.keys()在 TypeScript 中返回string[] ,但我断言它将是attribute类型的已知键的数组。这在技术上并不安全,但我假设您的输入将里面没有额外的意外键。

这给出了您提到的输入/输出关系,并且编译器知道 output 类型:

const str = mapToPlainObject({ "S": "2015-02-18T20:27:36.165Z" });
// const str: string;
console.log(str); // "2015-02-18T20:27:36.165Z"
const num = mapToPlainObject({ "N": 10 });
// const num: number;
console.log(num); // 10

您可能还有其他需要更复杂类型签名的用例; 如果是这样,请将它们添加到问题中,以便解决它们。 否则,希望有所帮助; 祝你好运!

Playground 代码链接

暂无
暂无

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

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