打字稿:属性 基于另一个 属性
Typescript: property based on another property
我遇到了嵌套类型的情况,我想实现的是根据另一个 属性 的值指定一个 属性。
在 HTML 中,我循环 API 的响应,并且根据收到的类型值,我想要一个不同的选项值。
例如:如果我收到类型为 'articles' 的响应,我希望将 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;
}
谢谢。
或许您可以在 class 中使用 setter 作为字段。每次为此字段设置值时都会调用此方法。
在 setter 中您也可以更改其他字段的值。
https://www.geeksforgeeks.org/typescript-accessor/
注意:您可能需要 class 而不是 ChatPayload 的接口
您可以使用 conditional types 强制 chatPayload
中的类型与 chatPayload.options
中的类型相同。
ChatPayload 可以将 "type" 来自 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 获得的响应符合您的预期。
我遇到了嵌套类型的情况,我想实现的是根据另一个 属性 的值指定一个 属性。
在 HTML 中,我循环 API 的响应,并且根据收到的类型值,我想要一个不同的选项值。
例如:如果我收到类型为 'articles' 的响应,我希望将 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;
}
谢谢。
或许您可以在 class 中使用 setter 作为字段。每次为此字段设置值时都会调用此方法。
在 setter 中您也可以更改其他字段的值。
https://www.geeksforgeeks.org/typescript-accessor/
注意:您可能需要 class 而不是 ChatPayload 的接口
您可以使用 conditional types 强制 chatPayload
中的类型与 chatPayload.options
中的类型相同。
ChatPayload 可以将 "type" 来自 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 获得的响应符合您的预期。