I want to declare a type for an array that can contain maximum one of the following strings: 'first'
, 'second'
, 'third'
.
Some valid examples of how that array could be:
[]
[ 'first' ]
[ 'first', 'second' ]
[ 'first', 'second', 'third' ]
[ 'first', 'third' ]
[ 'second', 'third' ]
Some invalid arrays:
[ 'other-value' ]
// no other values should be accepted[ 'first', 'first' ]
// no duplicates accepted
The types I've wrote:
export enum MyOptions {
first = 'first',
second = 'second',
third = 'third'
}
export type MyType = {
name: string;
email: string;
listings: {
MyOptions;
}[];
};
It has a warning saying Member 'MyOptions' implicitly has an 'any' type, but a better type may be inferred from usage.
So if it is changed to:
export type MyType = {
name: string;
email: string;
listings: {
options: MyOptions;
}[];
};
Now, there is no warning but it has that extra options
value that I don't think it must be added.
Any ways to fix this?
I want to declare a type for an array that can contain maximum one of the following strings: 'first'
, 'second'
, 'third'
.
Some valid examples of how that array could be:
[]
[ 'first' ]
[ 'first', 'second' ]
[ 'first', 'second', 'third' ]
[ 'first', 'third' ]
[ 'second', 'third' ]
Some invalid arrays:
[ 'other-value' ]
// no other values should be accepted[ 'first', 'first' ]
// no duplicates accepted
The types I've wrote:
export enum MyOptions {
first = 'first',
second = 'second',
third = 'third'
}
export type MyType = {
name: string;
email: string;
listings: {
MyOptions;
}[];
};
It has a warning saying Member 'MyOptions' implicitly has an 'any' type, but a better type may be inferred from usage.
So if it is changed to:
export type MyType = {
name: string;
email: string;
listings: {
options: MyOptions;
}[];
};
Now, there is no warning but it has that extra options
value that I don't think it must be added.
Any ways to fix this?
Share Improve this question edited Aug 15, 2022 at 12:06 Leo Messi asked Aug 15, 2022 at 10:09 Leo MessiLeo Messi 6,23622 gold badges80 silver badges155 bronze badges4 Answers
Reset to default 6You can use the Set
data structure.
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'])
}
Then you will be sure that there are no repeated options in your listing.
Note: actually you can pass repeated options but Set
will ignore them.
I think you have an extra set of braces that you don't need.
export type MyType = {
name: string;
email: string;
listings: {
MyOptions;
}[];
};
should be changed to
export type MyType = {
name: string;
email: string;
listings: MyOptions[];
};
You also have a more concise option: use string literal types:
export type MyType = {
name: string;
email: string;
listings: ('first' | 'second' | 'third')[];
};
It should be like this:
export type MyType = {
name: string;
email: string;
listings: MyOptions[];
};
Let's assume you have variable named x
of MyType
, then to push new value to listings
member you can do x.listings.push(MyOptions.first)
The second solution just means that you now have an object that could look like:
const exampleObject = {
name: 'Ralf';
email: '[email protected]';
listings: {
options: 'first';
}[];
};
Which is not what you intend, because you can´t have a ['first', 'second'] there, but only ONE value.
If you use the style
listings: MyOptions[];
Then it allows also the content ['first', 'first']
.
As far as i know, there is no way to limit the possible values not only by its content, but also by its amount (having at maximum one of each values) via typescript types.
So you would have to create your own logic.
For example having a small business object
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;
}
}
Now you can have your wrapper type:
export type MyType = {
name: string;
email: string;
listings: Options
};
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744228850a4564143.html
评论列表(0条)