-
Notifications
You must be signed in to change notification settings - Fork 12.9k
Closed as not planned
Closed as not planned
Copy link
Labels
Design LimitationConstraints of the existing architecture prevent this from being fixedConstraints of the existing architecture prevent this from being fixed
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
Metadata
Metadata
Assignees
Labels
Design LimitationConstraints of the existing architecture prevent this from being fixedConstraints of the existing architecture prevent this from being fixed