![](/img/trans.png)
[英]TypeScript: How to create an interface for an object with many keys of the same type and values of the same type?
[英]TypeScript: How to create a type or interface that is an object that has one of n keys or is a string?
我需要创建一个接口,它是一个字符串或一个具有三个键之一的对象。
基本上我有一个函数,根据错误返回一些东西:
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
,如果它有一个键,它只有一个。
你会如何设计这样的类型或界面?
编辑:我试图使通过给他们一个问号可选的钥匙,但后来我的棉短绒在各个键的错误return语句抱怨determineError
。
如果我正确理解你,只需将参数声明为ServerAlerts
或string
:
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)
这表明您可能只在参数签名中使用object
。 如果你想要求这三个领域之一(我相信会做掉与UNKNOWN_ERROR
分支),您可以定义三种接口,使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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.