Typescript: свойство, основанное на другом свойстве - PullRequest
2 голосов
/ 31 марта 2020

У меня есть ситуация с вложенными типами, и я хотел бы получить указанное свойство, основанное на значении другого свойства.

В HTML я циклически повторяю ответ API и, на основе для полученного значения типа я хотел бы иметь другое значение параметра.

Например: если я получаю ответ, где типом является «статьи», я хотел бы иметь OptionArticles в качестве ChatOptions.

Есть ли решение для этого?

Это код:

export interface ChatMessage {
    status: string;
    query: string;
    step: string;
    richResponse: boolean;
    payload: ChatPayload;
    sessionId?: number;
}

interface ChatPayload {
    type: ChatTypes;
    options: ChatOptions;
    confidence?: number;
    gotAllParams?: boolean;
}

type ChatTypes = 'text' | 'date' | 'articles' | 'params';

type ChatOptions = OptionText | OptionArticles | OptionParams;

interface OptionText {
    type: 'text' | 'date';
    text: string[];
}

interface OptionArticles {
    type: 'articles';
    prefilled: Values[];
    possible: Values[];
}

interface OptionParams {
    type: 'params';
    params: FineParams;
}

Спасибо.

Ответы [ 2 ]

2 голосов
/ 01 апреля 2020

Вы можете использовать условные типы для обеспечения того, что тип в chatPayload совпадает с типом в chatPayload.options.

ChatPayload может принимать в качестве параметра типа «тип» "из API:

interface ChatPayload<Type extends ChatTypes> {
    type: Type;
    options: Type extends "articles" ? OptionArticles : Type extends "params" ? OptionParams : OptionText ;
    confidence?: number;
    gotAllParams?: boolean;
}

И вы можете переключать тип в зависимости от значения поля в ответе API:

// the response you get from the API; you don't know the type yet
const apiResponse: any = {}

if (apiResponse.type === "text" || apiResponse.type === "date") {
    doSomething(apiResponse as ChatPayload<"text" | "date">)
} else if (apiResponse.type === "articles") {
    doSomething(apiResponse as ChatPayload<"articles">)
} else if (apiResponse.type === "params") {
    doSomething(apiResponse as ChatPayload<"params">)
} else {
    throw new Error("unexpected type")
}

Приведение немного уродливо, но вы придется использовать приведение, чтобы получить нетипизированный ответ API на один из ваших собственных типов.

Для дополнительной безопасности вы можете использовать валидатор JSON, чтобы убедиться, что ответ, который вы получаете от API соответствует тому, что вы ожидаете.

Машинописная игровая площадка

0 голосов
/ 31 марта 2020

Может быть, вы можете использовать сеттер для поля в вашем классе. Этот метод будет вызываться каждый раз, когда для этого поля устанавливается значение.

В установщике вы также можете изменить значение другого поля.

https://www.geeksforgeeks.org/typescript-accessor/

Примечание. Возможно, вам придется заняться классом вместо интерфейс для ChatPayload

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...