typescript - 如何确保一个接口只包含另一个接口的属性?
问题描述
假设我有以下界面。
interface Client {
id: number;
email: string;
firstName: string;
lastName: string;
cellNumberFull: string;
}
而且我希望以下界面仅包含GoClient
.
interface ClientRestricted {
firstName: string;
lastName: string;
cellNumberFull: string;
foo: string; // This would throw an error
}
寻找一些与扩展相反的国王。这样的事情存在吗?
解决方案
我倾向于让你的接口扩展一个映射的条件类型,它本身就是一个函数。这是一个递归类型定义(称为F-bounded quantification),可让您执行一些相当强大(如果令人困惑)的类型约束。例如:
type Restrict<T, U> = { [K in keyof U]: K extends keyof T ? T[K] : never };
type RestrictClient<U> = Restrict<Client, U>;
// okay as desired
interface Okay extends RestrictClient<Okay> {
firstName: string;
lastName: string;
cellNumberFull: string;
}
// error, as desired
interface Extra extends RestrictClient<Extra> {
// ~~~~~
// Types of property 'foo' are incompatible.
// Type 'string' is not assignable to type 'never'.
firstName: string;
lastName: string;
cellNumberFull: string;
foo: string;
}
通过制作你的新界面I extends RestrictClient<I>
,当且仅当I
is assignable to RestrictClient<I>
,意思是 if I
is assignable to ,意思是{[K in keyof I]: K extends keyof Client ? Client[K] : never}
如果每个 keyK
存在并且是相同(或更窄)类型时,这将起作用。I
Client
这也给出了以下行为,这可能会或可能不会解决您的用例:
// okay to narrow properties
interface Narrowed extends RestrictClient<Narrowed> {
firstName: "specificString";
}
// error to widen properties
interface Widened extends RestrictClient<Widened> {
// ~~~~~~~ <-- number not assignable to string
firstName: string | number;
}
// error to change property to unrelated types
interface Unrelated extends RestrictClient<Unrelated> {
// ~~~~~~~~~ <-- number not assignable to string
firstName: number;
}
如果它与您要查找的内容不完全匹配,您可以更改 的定义Restrict
以更紧密地对齐。无论如何,希望这能给你一些想法。祝你好运!
推荐阅读
- python - 根据日期从数据框中提取值
- java - 网络接口:您无权在该设备上捕获(套接字:不允许操作)
- flask-login - 带有 SQLALCHEMY_BINDS 的烧瓶安全性丢失静态文件池的连接
- unity3d - 如何在 Unity 中集成 xBim?
- akamai - WAF 的 ERR_HRS_SPACE_IN_HDR_NAME 失败原因
- python - 将元组转换为嵌套列表的索引
- javascript - 如何使用JS更改元素下的html元素中的文本
- python - 如何在使用谷歌 API 时遍历数据框中的行
- android - 如何使用 Mapbox 设置设备位置的标题?
- ios - Combine framework retry after delay?