gpt4 book ai didi

TypeScript:如何创建一个类型或接口(interface),它是一个具有 n 个键之一或者是字符串的对象?

转载 作者:搜寻专家 更新时间:2023-10-30 21:09:59 25 4
gpt4 key购买 nike

我需要创建一个接口(interface),该接口(interface)可以是字符串,也可以是具有三个键之一的对象。

基本上我有一个函数,它根据错误返回一些东西:

export const determineError = (error: ServerAlerts): AlertError => {
if (typeof error !== "string") {
if (error.hasOwnProperty("non_field_errors")) {
return error.non_field_errors[0];
} else if (error.hasOwnProperty("detail")) {
return error.detail;
} else if (error.hasOwnProperty("email")) {
return error.email[0];
} else {
return UNKNOWN_ERROR;
}
} else {
return error;
}
};

以下是类型:

export type AlertError =
| "Unable to log in with provided credentials."
| "E-mail is not verified."
| "Password reset e-mail has been sent."
| "Verification e-mail sent."
| "A user is already registered with this e-mail address."
| "Facebook Log In is cancelled."
| string;

export interface ServerAlerts {
non_field_errors: [string];
detail: string;
email: [string];
}

但是我在这里设计 ServerAlerts 的方式对我不起作用,因为 ServerAlerts 也可以是一个 string 并且如果它有它的键之一,它只有一个.

您将如何设计这样的类型或接口(interface)?

编辑:我尝试通过给键一个问号来使键可选,但随后我的 linter 在 determineError 中相应键的错误返回语句中提示。

最佳答案

如果我的理解正确,只需将参数声明为 ServerAlertsstring:

export const determineError = (error: ServerAlerts|string): AlertError => {
// -----------------------------------------------^^^^^^^

在评论中,您说过所有三个 ServerAlerts 属性都是可选的,因此您需要使用 ? 标记它们:

interface ServerAlerts {
non_field_errors?: [string];
detail?: string;
email?: [string];
}

但是,这意味着任何类型的 object 也可以工作,因为所有字段都是可选的。所以如果你同时做这两件事,你会得到:

determineError("foo");                       // Works
determineError({ non_field_errors: ["x"] }); // Works
determineError({ detail: "x" }); // Works
determineError({ email: ["x"] }); // Works
determineError({}); // Works (because all fields are optional)
let nonLiteralServerAlerts: object;
nonLiteralServerAlerts = { foo: ["x"] };
determineError(nonLiteralServerAlerts); // Works (because all fields are optional)
determineError({ foo: ["x"] }); // Fails (correctly)

Playground example

这表明您可以在参数签名中使用 object。如果你想要求三个字段之一(我相信这会取消 UNKNOWN_ERROR 分支),你将定义三个接口(interface)并制作 ServerAlerts 它们的联合:

interface ServerAlertsNonFieldErrors {
non_field_errors: [string];
}

interface ServerAlertsDetail {
detail: string;
}

interface ServerAlertsEmail {
email: [string];
}

type ServerAlerts = ServerAlertsNonFieldErrors | ServerAlertsDetail | ServerAlertsEmail;

然后在返回特定字段时使用类型断言:

if (error.hasOwnProperty("non_field_errors")) {
return (error as ServerAlertsNonFieldErrors).non_field_errors[0];
// ------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

如果你这样做,那么你会得到:

determineError("foo");                       // Works
determineError({ non_field_errors: ["x"] }); // Works
determineError({ detail: "x" }); // Works
determineError({ email: ["x"] }); // Works
determineError({}); // Fails (correctly)
let nonLiteralServerAlerts: object;
nonLiteralServerAlerts = { foo: ["x"] };
determineError(nonLiteralServerAlerts); // Fails (correctly)
determineError({ foo: ["x"] }); // Fails (correctly)

Playground Example

关于TypeScript:如何创建一个类型或接口(interface),它是一个具有 n 个键之一或者是字符串的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52681528/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com