Closed as not planned
Closed as not planned
Description
π Search Terms
type predicate, function overload, discriminating unions
π Version & Regression Information
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about method overload, unions
β― Playground Link
π» Code
type A_T = `A${string}`;
type B_T = `B${string}`;
type A_non_literal = 'ASD';
type B_non_literal = 'BSD';
const typePredicateA_non_literal = (val: any): val is A_non_literal => val.startsWith('A');
const typePredicateB_non_literal = (val: any): val is B_non_literal => val.startsWith('A');
function fntypePredicateA_non_literal(val: any): val is A_non_literal { return val.startsWith('A')};
function assertIsA_non_literal(val: any): asserts val is A_non_literal {
if (!typePredicateA(val)) {
throw new Error("Not a string!");
}
}
const typePredicateA = (val: any): val is A_T => val.startsWith('A');
const typePredicateB = (val: any): val is B_T => val.startsWith('B');
function fntypePredicateA(val: any): val is A_T { return val.startsWith('A');}
function assertIsA(val: any): asserts val is A_T {
if (!typePredicateA(val)) {
throw new Error("Not a string!");
}
}
function assertIsB(val: any): asserts val is B_T {
if (!typePredicateB(val)) {
throw new Error("Not a string!");
}
}
function createAorB(a: A_T, p0: number): number
function createAorB(b: B_T, p0: string): number
function createAorB(...[aOrB, p0]: [a: A_T, p0: number] | [b: B_T, p0: string] ): number {
if(typePredicateA(aOrB)){
console.log(Math.sqrt(p0)); // this throws compilation error
}
if(fntypePredicateA(aOrB)){
console.log(Math.sqrt(p0)); // this throws compilation error
}
assertIsA(aOrB);
console.log(Math.sqrt(p0));
return 0;
}
function create2AorB(a: A_non_literal, p0: number): number
function create2AorB(b: B_non_literal, p0: string): number
function create2AorB(...[aOrB, p0]: [a: A_non_literal, p0: number] | [b: B_non_literal, p0: string] ): number {
if(typePredicateA_non_literal(aOrB)){
console.log(Math.sqrt(p0)); // this throws compilation error
}
if(fntypePredicateA_non_literal(aOrB)){
console.log(Math.sqrt(p0)); // this throws compilation error
}
assertIsA_non_literal(aOrB);
console.log(Math.sqrt(p0));
return 0;
}
π Actual behavior
After the type predicate, the second parameter isn't narrowed down to number, hence the error:
Argument of type 'string | number' is not assignable to parameter of type 'number'.
Type 'string' is not assignable to type 'number'.
After the assertion, the code works as expected.
π Expected behavior
Type predicate to do the same narrowing as type assertion.
Additional information about the issue
No response