Typescript: - создать общий c тип для функции, принимающей объект, имеющий один ключ в качестве типа значения, а тип возврата - значение - PullRequest
0 голосов
/ 11 июля 2020

Я изо всех сил пытаюсь ввести функцию. ниже ошибка бросания фрагмента в этой строке export type DataAttributeType<T> = BACKEND_PRIMITIVE[T];

Я хочу создать функцию, которая принимает пример ввода и возвращает пример вывода.

Пример 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, то тип возвращаемого значения должен быть строкой.

Помощь будет оценена

Ответы [ 2 ]

0 голосов
/ 12 июля 2020

Я не уверен на 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() возвращает string[] в TypeScript, но я утверждаю, что это будет массив известных ключей типа attribute. Это технически небезопасно, но я предполагаю, что ваш ввод будет не иметь в нем дополнительных неожиданных ключей.

Это дает указанное вами соотношение ввода / вывода, а компилятор знает тип вывода:

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

У вас могут быть другие варианты использования это требует более сложной подписи типа; если да, добавьте их в вопрос, чтобы их можно было решить. В противном случае, надеюсь, что это поможет; удачи!

Ссылка на код

0 голосов
/ 11 июля 2020

Вы должны определить разрешенные базовые типы. Затем определите свой класс атрибутов оболочки. Затем определите функцию, которая возвращает базовый тип из класса оболочки.

Пример упаковки и атрибута

    // 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));
...