You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
A Type Error occurs with using a generic that extends a branded intrinsic typeΒ #55040
/////////////////////////////////////////////////////////////////////////////////////////////// TypestypeBrandedNumber=number&{__branded: true}typeOperationIO<Textendsnumber>=TextendsBrandedNumber
? T
: number;/////////////////////////////////////////////////////////////////////////////////////////////// Functionfunctionsub<Textendsnumber>(a: OperationIO<T>,): (b: OperationIO<T>)=>OperationIO<T>{return(b)=>(b-a)asany;}/////////////////////////////////////////////////////////////////////////////////////////////// Tests// Make sure non-branded numbers work.consttestNumbers=sub(2)(3);// Make sure branded numbers work.functiontestWithoutGenerics(a: BrandedNumber,b: BrandedNumber){returnsub(a)(b);}// Subtypes of branded numbers should work too.functiontestWithGenerics<TextendsBrandedNumber>(a: T,b: T){returnsub(a)(b);// <-- Why is this not allowed?}// Has correct typing dispite above error.consttestResultWithGenerics=testWithGenerics(2asBrandedNumber&{__foo: 1},3asBrandedNumber&{__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.
Yeah, it does seem to be that issue that's occurring. Any suggestions on how I can work around it? The only solution I've come up with is to use overloads of the sub function.
Also, "instinct" was a mistake by me, I meant "intrinsic".
changed the title [-]A Type Error occurs with using a generic that extends a branded instinct type[/-][+]A Type Error occurs with using a generic that extends a branded intrinsic type[/+]on Jul 17, 2023
The conventional term is "primitive", though. In TypeScript, "intrinsic" refers to compiler-provided types that users cannot implement themselves (see #40580), and while one could make a case that all primitive types are intrinsic, not all intrinsic types are primitive.
Activity
fatcerberus commentedon Jul 17, 2023
What is an βinstinct typeβ?
jcalz commentedon Jul 17, 2023
From context I'd say it means "primitive type"? π€·ββοΈ
The issue here is probably just that generic conditional types don't consult the generic's constraints and therefore remain unresolved, as in #31096
RebeccaStevens commentedon Jul 17, 2023
Yeah, it does seem to be that issue that's occurring. Any suggestions on how I can work around it? The only solution I've come up with is to use overloads of the
subfunction.Also, "instinct" was a mistake by me, I meant "intrinsic".
[-]A Type Error occurs with using a generic that extends a branded instinct type[/-][+]A Type Error occurs with using a generic that extends a branded intrinsic type[/+]jcalz commentedon Jul 17, 2023
The conventional term is "primitive", though. In TypeScript, "intrinsic" refers to compiler-provided types that users cannot implement themselves (see #40580), and while one could make a case that all primitive types are intrinsic, not all intrinsic types are primitive.
RebeccaStevens commentedon Jul 17, 2023
Ahh, good to know. I've kind of just been using the two interchangeably.
RyanCavanaugh commentedon Jul 18, 2023
For this substitution to be safe, the conditional type would have to be nondistributive. If you change this to
then it indeed works as expected