Skip to content

Instantly share code, notes, and snippets.

@masaeedu
Last active January 17, 2024 23:11
Show Gist options
  • Save masaeedu/becdacf5fdebadf33f7e9b8f2af1e9d8 to your computer and use it in GitHub Desktop.
Save masaeedu/becdacf5fdebadf33f7e9b8f2af1e9d8 to your computer and use it in GitHub Desktop.

Thank you for the helpful response and pointers. I think I need to take my time to sort this out, thanks a lot and I'll come back with a better understanding, hopefully!

I did my homework. Now I'm not so certain about everything, so please take this with a grain of salt.

Typescript's generic functions seem to act like they're contravariant over the type parameter's type bound. I'm not entirely sure though.

Playground Link

// Assignment succeeds with F<unknown> -> F<string>
// Assignment fails with F<string> -> F<unknown>

const a1: <T extends unknown>(x: T) => T = (x) => x;
const b1: <U extends string>(y: U) => U = a1;
const c1: typeof a1 = b1; // error

const a2: <T extends unknown>(x: T) => string = String;
const b2: <U extends string>(x: U) => string = a2;
const c2: typeof a2 = b2; // error

declare const a3: <T extends unknown>() => T;
const b3: <U extends string>() => U = a3;
const c3: typeof a3 = b3; // error

@masaeedu This seems like the {co,contra}variance of the types is independent to whether you can do a {co,contra}map on it. May I ask, did I mess up again, or is this another unsoundness, or is this the way it is? Anyhow thank you so much for the helpful discussion! heart

@masaeedu
Copy link
Author

@nightlyherb No worries at all. Sorry I haven't responded yet, life keeps getting in the way. FWIW your new snippet with F1, F2, and F3 also raises a bunch of interesting (read thorny) questions, you seem to have quite a knack for doing that :). I made several attempts at writing up a response but kept running out of time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment