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
// These are the types of records in the database.typeTableToRecord={a: {a: number}b: {b: string}c: {c: string[]}}typeTable=keyofTableToRecord// Create a union of {table, id} objects.typePointer<TextendsTable=Table>={[KinT]: {table: K,id: string}}[T]// Hover X to see this is a proper union typetypeX=Pointer// β this works as expected.declarefunctiongetRecord<TextendsTable>(pointer: Pointer<T>): TableToRecord[T]constx=getRecord({table: "a",id: ""})// β this surprisingly doesn't workdeclarefunctionsomething(pointer: Pointer): voidconstp: Pointer<"a">={table: "a",id: ""}something(p)functionrun<TextendsTable>(pointer: Pointer<T>){constx=something(pointer)}// β However, this does work if run is generic on Pointer instead of Table.declarefunctionsomething2(pointer: Pointer): voidfunctionrun2<PextendsPointer>(pointer: P){constx=something(pointer)}// β Which then makes me wonder if its better to write getRecord this waydeclarefunctiongetRecord2<PextendsPointer>(pointer: P): TableToRecord[P["table"]]constx2=getRecord2({table: "a",id: ""})
π Actual behavior
I'm surprised by this error where Pointer<T> where T extends Table doesn't satisfy the argument Pointer<Table>.
If we were talking arrays, Array<T> where T extends string | number, I'd imagine you should be able to pass that to a function that accepts Array<string | number> as an argument. But it is a bit tricky if that argument gets mutated by the function, e.g. pushing a number onto a string array. I think there's a fancy type-system word for this behavior?
But as I understand it, TypeScript is all structural comparison and since Pointer<T> unfurls into the union type, I'm curious where the problem lies and it seems to me like the type system should let this work...
I noticed when the generic param is P extends Pointer instead of T extends Table and then using Pointer<T>, then the code does work. But then that leads me to wonder if there's any difference between function getRecord<T extends Table>(pointer: Pointer<T>): TableToRecord[T] and function getRecord2<P extends Pointer>(pointer: P): TableToRecord[P["table"]] ...
π Expected behavior
The text was updated successfully, but these errors were encountered:
Info: Pointer<T> is a distributive object type as coined in #47109
I think that if F<T> is a distributive object type, then F<T> is covariant in T (at least if T is only allowed to be unit types or unions of unit types). TS seems to recognize that F<T> extends F<U> when T extends U if U is generic, but not if U is specific. Not sure if this is a design limitation or a missing feature or something intentional.
Anyway I hope we can amend the title to something more specific?
Bug Report
π Search Terms
π Version & Regression Information
β― Playground Link
Playground link with relevant code
π» Code
π Actual behavior
I'm surprised by this error where
Pointer<T>
whereT extends Table
doesn't satisfy the argumentPointer<Table>
.If we were talking arrays,
Array<T>
whereT extends string | number
, I'd imagine you should be able to pass that to a function that acceptsArray<string | number>
as an argument. But it is a bit tricky if that argument gets mutated by the function, e.g. pushing a number onto a string array. I think there's a fancy type-system word for this behavior?But as I understand it, TypeScript is all structural comparison and since
Pointer<T>
unfurls into the union type, I'm curious where the problem lies and it seems to me like the type system should let this work...I noticed when the generic param is
P extends Pointer
instead ofT extends Table
and then usingPointer<T>
, then the code does work. But then that leads me to wonder if there's any difference betweenfunction getRecord<T extends Table>(pointer: Pointer<T>): TableToRecord[T]
andfunction getRecord2<P extends Pointer>(pointer: P): TableToRecord[P["table"]]
...π Expected behavior
The text was updated successfully, but these errors were encountered: