type guard multiple parameters
I'd like to write a type guard that takes two parameters and changes the type of both of them.
My specific use case is to try to make the following pattern (somewhat) more type-safe:
class Foo<TFeature, TOther> {
// If featureCtor is null, TFeature will never be used.
constructor(private readonly featureCtor: { new(): TFeature } | null) { }
isFeature(thing: any): thing is TFeature {
return !!this.featureCtor && thing instanceof this.featureCtor;
}
bar(thing: TFeature|TOther) {
if (this.isFeature(thing)) {
// Type guard should prove that this.featureCtor is not null
new this.featureCtor();
} else {
// Type guard should prove this
const x: TOther = thing;
}
}
}
isFeature(thing: any, ctor: { new(): TFeature } | null): (thing is TFeature)&(ctor is { new(): TFeature }) {
return !!this.featureCtor && thing instanceof this.featureCtor;
}
It would be even nicer to allow type guards to operate on readonly fields, so I wouldn't need to pass this.featureCtor
as a parameter.
I also tried
constructor(private readonly featureCtor: TFeature extends never ? null : { new(): TFeature }) { }
But that didn't work.
My suggestion meets these guidelines:
Any news on this?
Seconding a need for this:
const isValidPair = (x: null | string, y: null | string): x is string & y is null {
return typeof x === 'string' && y === null;
};
if (isValidPair(var1, var2)) {
// know var1 is string
// know var2 is null
}
This would be useful for processing overloaded function parameters where it is enough to check one parameter to assume the type of the other parameter:
function nonsense(a: number, b: number): number;
function nonsense(a: string, b: string): string;
function nonsense(a: number | string, b: number | string): number | string {
const isNumbers = (a: number | string, b: number | string): a is number & b is number
=> typeof a === "number";
if (isNumbers(a, b)) {
return a * 10 + b * 100;
} else {
return a.length + b.length;
}
}
This is also convenient and meaningful for builders.
class Builder {
private fixtureA: string | null = null
private fixtureB: string | null = null
// ... any other C, D, E ...
public build() {
if (this.ofTypeAB()) {
return {}
}
if (this.ofTypeCDA()) {
return {}
}
}
}
Hi, any updates?
Most helpful comment
Seconding a need for this: