比如我想要 sex 属性为 male 时,tes 属性为 string,为 female 时,test 属性为 number
enum ESex {
Male,
Female
}
interface IPerson {
sex: ESex;
test: string | number;
}
const persons: IPerson[] = [
{
sex: ESex.Male,
test: 1
},
{
sex: ESex.Female,
test: ''
}
];
不能使用泛型,因为 person 总是呈现为数组形式,没法一个个添加泛型
interface IPersonA {
sex: ESex.Male;
test: string
}
interface IPersonB {
sex: ESex.Female;
test: number
}
const persons: Array
= [
{
sex: ESex.Male,
test: 'a'
},
{
sex: ESex.Female,
test: 1
}
];
```javascript
enum Sex {
Male,
Female
}
type Person = {
sex: Sex.Female,
test: number,
} | {
sex: Sex.Male,
test: string,
}
const persons: Array = [
{
sex: Sex.Male,
test: ""
},
{
sex: Sex.Female,
test: 1
}
];
```
嗯,可以用联合类型包起来。
不知道有没有更好的方法
确实是个方法,但是如果属性比较多的话,写起来有点麻烦,我是想使用 extends 关键字实现的,但是 extends 关键字是匹配类型的,但是我这个好像涉及到了具体的值
先分别定义 MalePerson 和 FemalePerson 两个接口,然后定义联合类型,type Person = MalePerson | FemalePerson
看了下类似于 T extends K ? number : string 这样的方式。 但是这个场景套不进去。。
这个可以用 conditional type 做,就是楼上说的 T extends K。你把枚举替换成 type Gender = ‘male’ | ‘female’即可。
手机打字,单引号不正确
哦,看楼上的例子,枚举的字面值本身也可以做类型,那么
type Data = T extends Geneder.Male ? string : (T extends Gender.Female ? number : never)
即可
嗯,我也试出来了, 但是感觉这样写太不直观了。 还是分成 2 个 interface 好一点
编码上确实不是很直观,但是语义上这边相当于定义了一个简单的 type-level function,我觉得更清楚,更方便代码复用。看个人喜好吧,如果只有一两处使用,interface 自然是不错的选择。
可以用 type 来定义:
enum ESex {
Male,
Female,
}
type IPerson = {
sex: ESex.Male;
test: number;
} | {
sex: ESex.Female;
test: string;
};
const persons: IPerson[] = [
{
sex: ESex.Male,
test: 1,
},
{
sex: ESex.Female,
test: '',
}
];
老铁,您能用 Gender 吗?别用 sex
这个需求如果放在函数中,可以通过函数的重载来实现。和这里定义 2 个 interface 是一样的性质
这个应用场景下 type Data 怎么放到 interface Person 下呢?
这里就需要一个 generic interface:interface Person { gender: Gender; someFieldA: FieldA; someFieldB: FieldB }
谢谢,我也是这样想的,确认一下有没有更好的写法