Closed
Description
Bug Report
π Search Terms
- generics
- branded
- intrinsic type
π Version & Regression Information
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about generics
β― Playground Link
Playground link with relevant code
π» Code
/////////////////////////////////////////////////////////////////////////////////////////////
// Types
type BrandedNumber = number & {
__branded: true
}
type OperationIO<T extends number> = T extends BrandedNumber
? T
: number;
/////////////////////////////////////////////////////////////////////////////////////////////
// Function
function sub<T extends number>(
a: OperationIO<T>,
): (b: OperationIO<T>) => OperationIO<T> {
return (b) => (b - a) as any;
}
/////////////////////////////////////////////////////////////////////////////////////////////
// Tests
// Make sure non-branded numbers work.
const testNumbers = sub(2)(3);
// Make sure branded numbers work.
function testWithoutGenerics(a: BrandedNumber, b: BrandedNumber) {
return sub(a)(b);
}
// Subtypes of branded numbers should work too.
function testWithGenerics<T extends BrandedNumber>(a: T, b: T) {
return sub(a)(b); // <-- Why is this not allowed?
}
// Has correct typing dispite above error.
const testResultWithGenerics = testWithGenerics(
2 as BrandedNumber & { __foo: 1},
3 as BrandedNumber & { __foo: 1}
);
π Actual behavior
TypeScript reports a type error on line 35.
π Expected behavior
No error should be reported because as far I can tell, this line should be valid. Additionally, TypeScript can successfully deduce the type on line 39.