Is there a way for typescript to know that either this.a
will be set or this.b
and this.c
will be set?
Taking the following code, there should never be an instance where all items will be set or none will be set due to how the constructor is setup.
export class MyClass {
readonly a?: SomeClass
readonly b?: string
readonly c?: string
constructor(a: SomeClass)
constructor(b: string, c: string)
constructor(...args: ([SomeClass] | [string, string])) {
if(args.length === 1) {
this.a = args[0]
} else {
this.b = args[0]
this.c = args[1]
}
}
echo() {
if (this.a instanceof SomeClass) {
} else {
someFunction(this.b, this.c)
}
}
}
someFunction
is giving the following error:
Argument of type 'string | undefined' is not assignable to parameter of type 'string'.
I know I could do an else if(typeof this.b === 'string' && typeof this.c === 'string')
, but that seems like a long approach. Is there another way that this could be done?
CodePudding user response:
Either property "a" is set or property "b" and "c" is set
The key concept here is "or". Use a TypeScript union type to achieve it i.e. {a} | {b,c}
. Here is a complete example:
class SomeClass { };
export class MyClass {
readonly values: { a: SomeClass } | { b: string, c: string }
constructor(a: SomeClass)
constructor(b: string, c: string)
constructor(...args: ([SomeClass] | [string, string])) {
if (args.length === 1) {
this.values = { a: args[0] };
} else {
this.values = { b: args[0], c: args[1] };
}
}
echo() {
if ('a' in this.values) {
const { a } = this.values;
} else {
const { b, c } = this.values;
}
}
}
CodePudding user response:
//you can ignore undefined
if (!this.a) {
someFunction(this.b!, this.c!)
}
// or better way: check if strings are assigned
if(this.b && this.c){
someFunction(this.b, this.c)
}