I have a very simple example, to demonstrate the issue:
class Person {
_name = '';
_age = 0;
get name() {
return this._name;
}
/**
* @type {string}
*/
set name(name) {
this._name = name;
}
get age() {
return this._age;
}
/**
* @type {number | string}
*/
set age(age) {
if (age === 'too old') {
age = 100000;
}
this._age = age;
}
}
I use VSCode to do typechecking, but why does it fail on the type?
I explicitly say that the age setter can take either a number or a string:
You didn't define the type but instead wrote a JSDoc comment. That doesn't actually affect your code. Thus TypeScript implicitly sets the type number
.
If you want the setter to accept both string
and number
one solution would be to use a union type like this:
set age(age: string | number) {
...
}
Keep in mind that you get problems when setting this._age
later on because this._age
also implicitly has the type number
(default value 0
) and therefore cannot be assigned a value of type string | number
string | number
.
I believe you need to wrap your union types in parenthesise to be valid in JSDoc:
/**
* @type {(number | string)}
*/
From the documentation :
Multiple types (type union) This can be a number or a boolean.{(number|boolean)} This means a value can have one of several types, with the entire list of types enclosed in parentheses and separated by |.
The following snippet should work. Just check the type of age
with typeof
to narrow the type into an if
statement.
class Person {
_name = '';
_age = 0;
get name() {
return this._name;
}
/**
* @param {string} name
*/
set name(name) {
this._name = name;
}
get age() {
return this._age;
}
/**
* @param {number | string} age
*/
set age(age) {
if (typeof age === 'string') {
if (age === 'too old') {
age = 100000;
} else {
age = parseInt(age)
}
}
this._age = age;
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.