![](/img/trans.png)
[英]Typescript - How to extends model with typescript interface
[英]How to reslove TypeScript Interface heavy load?
type ItemProps = {
a: string;
b?: boolean;
c?: string;
}
const arr: ItemProps[] = [
{
a: 'demo',
b: true,
c: 'test'
},
{
a: 'demo2'
}
];
如果 prop b
存在,如何定义ItemProps
。 如果 prop b
存在 prop c
必须定义?
我要这个:
const arr: ItemProps[] = [
{
a: 'demo',
b: true,
c: 'test'
},
{
a: 'demo2',
b: true, // ERROR, because b exist,but c undefined
}
];
使用联合类型:
type ItemProps = { a: string; } & ({} | { b: boolean; c: string; });
有了这个 Typescript 已经缩小了带有类型保护的联合类型,例如:
let item: ItemProps = { a: "test", b: true };
if("b" in item) {
type Narrowed = typeof item;
console.log(item.c)
} else {
type Narrowed = typeof item;
console.log(item.c); // ERROR
}
然而,不幸的是,有时 Typescript 允许指定比实际类型更多的属性,当类型是联合类型时,似乎就是这种情况。 因此,尽管使用联合类型,打字更准确,但在创建新的 ItemProps 期间它不会帮助你。
为此,您将需要一个可区分的 union ,例如,如果将两个不同的字符串文字类型用于共享属性a
:
type ItemProps = { a: "without" } | { a: "with", b: boolean; c: string; };
这样,在分配 object 文字时,联合将被区分为基于 a 的 object 类型之一,然后只能指定已知属性:
type ItemProps = { a: "without" } | { a: "with", b: boolean; c: string; };
const arr: ItemProps[] = [
{
a: 'with',
b: true,
c: 'test'
},
{
a: 'without',
b: true, // ERROR
},
{
a: 'with', // ERROR
}
];
拥有这样的区分属性在许多情况下非常有用,例如在条件逻辑中,因此您可能希望将这样的属性添加到数据 model 中。
if(item.a === "with") {
console.log(item.b, item.c); // works, as item got narrowed down
}
据我所知,没有办法通过界面来做到这一点。 您可以在添加数据之前在代码中检查它。 一个属性可以有多个接口。
例如:
const someItem:接口A | 接口B | 不明确的;
您可以在使用更新值之前进行检查
if(b) { someItem = value structured as InterfaceA } else { someItem = value structured as InterfaceB }
您还可以查看如何使用类和构造函数https://www.typescriptlang.org/docs/handbook/classes.html 。
多谢你们。 我得到了答案!
type ExcludeKeys<T> = { [P in keyof T]: never; };
type RequireOrExcludeKeys<T, Keys extends keyof T = keyof T> = Pick<T,Exclude<keyof T, Keys>> & (Required<Pick<T, Keys>> | ExcludeKeys<Pick<T, Keys>>);
type ItemProps = RequireOrExcludeKeys<{
a: string;
b?: boolean;
c?: string;
}, 'b' | 'c'>;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.