我想为数组声明一个类型,该类型最多可以包含以下字符串之一:'first'
、'second'
、'third'
。
关于该阵列的一些有效例子:
[]
[ 'first' ]
[ 'first', 'second' ]
[ 'first', 'second', 'third' ]
[ 'first', 'third' ]
[ 'second', 'third' ]
一些无效数组:
[ 'other-value' ]
//不接受其他值[ 'first', 'first' ]
//不接受重复
我写过的类型:
export enum MyOptions {
first = 'first',
second = 'second',
third = 'third'
}
export type MyType = {
name: string;
email: string;
listings: {
MyOptions;
}[];
};
它有一个警告,说成员"MyOptions"隐式具有"any"类型,但可以从用法推断出更好的类型。
因此,如果将其更改为:
export type MyType = {
name: string;
email: string;
listings: {
options: MyOptions;
}[];
};
现在,没有任何警告,但它有一个额外的options
值,我认为不必添加它。
有什么办法解决这个问题吗?
您可以使用Set
数据结构。
export type Options = 'first' | 'second' | 'third'
export type Listing = Set<Options>
export type MyType = {
name: string;
email: string;
listings: Listing;
};
const myType = {
name: 'name',
email: 'email',
listing: new Set(['first', 'second'])
}
然后,您将确保您的列表中没有重复的选项。注意:实际上您可以传递重复选项,但Set
会忽略它们。
我认为您有一组不需要的额外大括号。
export type MyType = {
name: string;
email: string;
listings: {
MyOptions;
}[];
};
应该改为
export type MyType = {
name: string;
email: string;
listings: MyOptions[];
};
您还有一个更简洁的选项:使用字符串文字类型:
export type MyType = {
name: string;
email: string;
listings: ('first' | 'second' | 'third')[];
};
应该是这样的:
export type MyType = {
name: string;
email: string;
listings: MyOptions[];
};
假设您有一个名为MyType
的x
的变量,然后要将新值推送给listings
成员,您可以执行x.listings.push(MyOptions.first)
第二个解决方案只是意味着您现在有了一个看起来像的对象
const exampleObject = {
name: 'Ralf';
email: 'XXX@XX.xx';
listings: {
options: 'first';
}[];
};
这不是你想要的,因为你不能有一个[第一个','第二个'],而只有一个值。
如果您使用样式
listings: MyOptions[];
然后它也允许内容CCD_ 19。
据我所知,没有办法通过typescript类型不仅通过其内容,而且通过其数量(每个值最多有一个(来限制可能的值。
所以你必须创建自己的逻辑。
例如,拥有一个小型业务对象
class Options {
private _values: MyOptions[] = [];
addOption(option:MyOption){
if(this._values.some(option)){
return; // or throw an error, depends on your usecase
}
this.values.concat(option);
}
get options():MyOptions{
return this._values;
}
}
现在你可以有你的包装类型:
export type MyType = {
name: string;
email: string;
listings: Options
};