// defining a type Combinable with string or number as possible values
type Combinable = string | number;
// function to check if parameter is a string
function isString(param: unknown): param is string {
return typeof param === "string";
}
/**
* Function add that expects parameters a and b to have the same subtype of Combinable,
* such as both being strings or numbers, and returns the same subtype of a and b.
*/
function add<T extends Combinable>(a: T, b: T): T {
if (isString(a)) {
// Error message: Type 'string' is not assignable to type 'T'.
// The constraint allows 'string', but 'T' could be a different subtype of Combinable.
// Why can't TS infer b must also be type "string" since a is narrowed down to "string"?
// let ta = typeof a // result: string & T === string
// let tb = typeof b // result: T why isn't it inferred as string?
return a + b;
} else {
// Same error occurs in this block when trying to add two numbers
return (a as number) + (b as number);
}
}
let a: Combinable = "123"; // variable a assigned a string value
let b: Combinable = 123; // variable b assigned a number value
// When calling the function add, I expect TS to infer that a and b should be the same subtype of Combinable
add(a, b);
My Questions:
- How can I resolve the assignment error?
- Why doesn't TS automatically infer that b should be type "string" after narrowing down a to "string"?
- Why can TS infer that a and b are the same subtype of Combinable when the function is called, but not within the function body?
I appreciate any insights or solutions you may have. Thank you.