any: magic, ill-behaved type that acts like a combination ofnever(the proper bottom type) andunknown(the proper top type)- Anything except
neveris assignable toany, andanyis assignable to anything at all. - Identities:
any & AnyTypeExpression = any,any | AnyTypeExpression = any - Key TypeScript feature that allows for gradual typing.
- Anything except
unknown: proper, well-behaved top type- Anything at all is assignable to
unknown.unknownis only assignable to itself (unknown) andany. - Identities:
unknown & AnyTypeExpression = AnyTypeExpression,unknown | AnyTypeExpression = unknown - Prefer over
anywhenever possible. Anywhere in well-typed code you're tempted to useany, you probably wantunknown. - Equivalent to
{} | null | undefined.
- Anything at all is assignable to
never: proper, well-behaved bottom type- Nothing besides itself (
never) is assignable tonever, butneveris assignable to anything at all. - Identities:
never & AnyTypeExpression = never,never | AnyTypeExpression = AnyTypeExpression - You'll see it in error messages related to exceptions and exhaustiveness checking, but you'll rarely write it outside of conditional types, where it's useful for "negating" a condition.
- Nothing besides itself (
null: the only proper unit type, though there are two other unit-like types- Nothing besides itself (
null),never, andanyare assignable tonull.nullis assignable to itself (null)
- Nothing besides itself (
undefined: unit-like type. Not quite a proper unit type because it's assignable tovoid(unit types are normally only assignable to themselves and the top type)- Nothing besides itself (
undefined),never, andanyare assignable toundefined.undefinedis only assignable tovoidand, as always, itself (undefined),unknown, andany.
- Nothing besides itself (
void: irregular [unit-like type]. Not a proper unit type becauseundefinedis assignable to it (normally nothing is assignable to a unit type except itself and the bottom type)- Besides itself (
void),never, andany, onlyundefinedis assignable tovoid.voidis only assignable to itself (void),unknown, andany. - Irregular because the set of values in this type is equal to the set of values that the
undefinedtype consists of, specifically, the JavaScript valueundefined. Normally that would make them the same unit type rather than two distinct unit-like types. - Useful to distinguish functions whose return value you aren't supposed to use at all, from functions whose return value may be the value
undefined. E.g. if you havefoo: () => voidandbar: (x?: string) => number, thenbar(foo())is a type error.
- Besides itself (
boolean,number,string,symbol: primitive types, all disjoint- All the primitive types are all disjoint from each other and from
null,undefined, andobject, which means none of them are assignable to each other. Only themselves and their literal types (andneverandany) are assignable to them, that is:- Only
trueandfalseare assignable toboolean(in fact,booleanis equivalent totrue | false). - Only number literal types like
0,1,42,-7,3.14are assignable tonumber. - Only string literal types like
"","asdf","etc."are assignable tostring. - There are no symbol literals, the only way to create symbols is the
Symbolconstructor.
- Only
- Primitive types are assignable to any subtype of the corresponding interface, for example
number, and any number literal type, is assignable to the interfaceNumber, or any subtype such as the interface{ toFixed(): string }.- This implies all 4 of these primitive types are assignable to
{}.
- This implies all 4 of these primitive types are assignable to
- All the primitive types are all disjoint from each other and from
- interface types:
{ whatever: AnyTypeExpression }- Assignable to subtypes like
{ a: number, b: string }is assignable to{ a: number }, and{ a: number }is assignable to{ readonly a: number }or{ a?: number }or{ [prop: string]: number }. - There are many built-in interface types, like
Object,Number,Date,RegExp,Array,ReadonlyArray, etc.Object,{},{ toString(): string }, and all other subtypes of theObjectinterface are all the same type, thanks to theObjectinterface being a pseudo-top type.Array<T>andReadonlyArray<T>can also be written with the syntactic sugarT[]andreadonly T[], respectively.
- Assignable to subtypes like
object: magic, but well-behaved refinement type, essentially{}but excluding the primitive types- Would be equivalent to
Exclude<{}, boolean | number | string | symbol>, ifExclude<_,_>worked on interface types that aren't union types.
- Would be equivalent to
-
Star
(144)
You must be signed in to star a gist -
Fork
(13)
You must be signed in to fork a gist
-
-
Save laughinghan/31e02b3f3b79a4b1d58138beff1a2a89 to your computer and use it in GitHub Desktop.
foo() === undefinedis a type error iffoo()returnsvoid
This doesn't seem to be true. Playground Link
Is it possible to assign an unknown value to a {} | null | undefined value since they are equivalent? How do you consume unknown values?
Dude, that's amazing. Thank you.
Thanks 👍
@anka-213 You're right—and more generally, an equality check between a subtype and supertype are always allowed, duh
Another mistake: there's actually no Infinity or NaN number literal type, because NaN is an ill-behaved value, so you can't type-narrow with ===. (There seems to be no good reason for the lack of an Infinity literal type.) microsoft/TypeScript#28682
Also, omissions, which I haven't fixed:
- tuple types
- intersection and union types
- enum types, which I believe are equivalent to unions of string/number literal types
Nothing besides itself (
never) andanyare assignable tonever, butneveris assignable to anything at all.
@tjjfvi Oh damn, you're right! Fixed the text, haven't fixed the diagram because I don't have the original editable version, I don't even remember how I made it lol
Also how are you all even finding this?
@laughinghan I was linked to it on the typescript discord, but this gist is the top google result for "typescript type diagram".
@tjjfvi Oh damn, you're right! Fixed the text, haven't fixed the diagram because I don't have the original editable version, I don't even remember how I made it lol
Also how are you all even finding this?
So, I think we need to fix this part as well:
Anything except never is assignable to "any", and "any" is assignable to anything at all.
to:
Anything is assignable to "any", and "any" is assignable to anything at all (except never).
declare const any: any;
const never: never = any; // Error
declare const never2: never
const any2: any = never // Oktype A = never extends any ? 1 : 2 // 1
type B = any extends never ? 1 : 2 // 1 | 2Any is a jocker.
nice!
These read helped me so much. Why something like this is not in the frontpage of the typescript docs? Sometimes i think conditional types are only a nightmare..
Again, good job.



Very nice