Last active
January 2, 2023 07:14
-
-
Save Offirmo/c6a67f81526eb2f43ae600523747ceaf to your computer and use it in GitHub Desktop.
[typescript conditional types playground] #typescript
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// type tester for generics | |
type ImmutablePrimitive = undefined | null | boolean | string | number | Function | |
interface EmptyStruct { } | |
// https://www.typescriptlang.org/docs/handbook/2/functions.html#other-types-to-know-about | |
//type T = any | |
//type T = unknown | |
//type T = void | |
//type T = undefined | |
//type T = object | |
//type T = never | |
//type T = null | |
//type T = boolean | |
type T = string | |
//type T = number | |
//type T = Function | |
//type T = () => number | |
//type T = string[] | |
//type T = Map<string, number> | |
//type T = { foo: number[] } | |
// // any unkn undefined object null string Function string[] Map<s,n> Struct | |
type KeyofT = keyof T // || nv nv nv ... nv x x | |
type ValuesOfT = T[keyof T] // any nv nv nv ... nv ... ... | |
type T_is_any = 0 extends 1 & T ? true : false // any✔ | |
type T_extends_any = T extends any ? true : false // any✔ undef✔ obj✔ nul✔ str✔ fn✔ str[]✔ map✔ stct✔ | |
type any_extends_T_00 = any extends T ? true : false // any✔ ? ? ? ? ? ? ? ? | |
type any_extends_T_01 = any extends [T] ? true : false // ?? ? ? ? ? | |
type any_extends_T_10 = [any] extends T ? true : false // any✔ obj✔ str[]✔ | |
type any_extends_T_11 = [any] extends [T] ? true : false // any✔ obj✔ fn✔ str[]✔ map✔ stct✔ | |
type T_extends_unknown = T extends unknown ? true : false // any✔ undef✔ obj✔ nul✔ str✔ fn✔ str[]✔ map✔ stct✔ | |
type unknown_extends_T = unknown extends T ? true : false // any✔ | |
type T_extends_never_00 = T extends never ? true : false // ?? | |
type T_extends_never_01 = T extends [never] ? true : false // ?? | |
type T_extends_never_10 = [T] extends never ? true : false // | |
type T_extends_never_11 = [T] extends [never] ? true : false // | |
type never_extends_T = never extends T ? true : false // any✔ undef✔ obj✔ nul✔ str✔ fn✔ str[]✔ map✔ stct✔ | |
type T_extends_string_0 = T extends string ? true : false // ?? | |
type T_extends_ip_00 = T extends ImmutablePrimitive ? true : false // ?? undef✔ nul✔ str✔ fn✔ | |
type T_extends_ip_01 = T extends [ImmutablePrimitive] ? true : false // ?? | |
type T_extends_ip_10 = [T] extends ImmutablePrimitive ? true : false // | |
type T_extends_ip_11 = [T] extends [ImmutablePrimitive] ? true : false // any✔ undef✔ nul✔ str✔ fn✔ | |
type T_extends_obj_0 = T extends object ? true : false // obj✔ | |
type T_extends_obj_01 = T extends [object] ? true : false // | |
type T_extends_obj_10 = [T] extends object ? true : false // obj✔ str✔ | |
type T_extends_obj_11 = [T] extends [object] ? true : false // obj✔ | |
type T_extends_array_00 = T extends Array<infer E> ? true : false // ?? str[]✔ | |
type T_extends_map_00 = T extends Map<infer K, infer V> ? true : false // ?? map✔ | |
type T_extends_map_01 = T extends [Map<infer K, infer V>] ? true : false // ?? | |
type T_extends_map_10 = [T] extends Map<infer K, infer V> ? true : false // | |
type T_extends_map_11 = [T] extends [Map<infer K, infer V>] ? true : false // any✔ map✔ | |
type T_extends_es_00 = T extends EmptyStruct ? true : false // ?? obj✔ str✔ fn✔ str[]✔ map✔ stct✔ | |
type T_extends_es_01 = T extends [EmptyStruct] ? true : false // ?? | |
type T_extends_es_10 = [T] extends EmptyStruct ? true : false // any✔ undef✔ obj✔ nul✔ str✔ fn✔ str[]✔ map✔ stct✔ | |
type T_extends_es_11 = [T] extends [EmptyStruct] ? true : false // any✔ obj✔ str✔ fn✔ str[]✔ map✔ stct✔ | |
export type ImmutableAny = Readonly<any> | |
export type ImmutableArray<T> = ReadonlyArray<Immutable<T>> | |
export type ImmutableMap<K, V> = ReadonlyMap<Immutable<K>, Immutable<V>> | |
export type ImmutableSet<T> = ReadonlySet<Immutable<T>> | |
export type ImmutableObject<T> = { +readonly [K in keyof T]: Immutable<T[K]> } | |
export type Immutable<T> = true extends false ? never | |
//: 0 extends 1 & T ? Readonly<any> | |
: unknown extends T ? unknown | |
: T extends Array<infer U> ? ImmutableArray<U> // | |
: T extends Map<infer K, infer V> ? ImmutableMap<K, V> // any matches by being distributive!! | |
: T extends Set<infer M> ? ImmutableSet<M> // any matches by being distributive!! | |
: T extends EmptyStruct ? ImmutableObject<T> // any is distributive + this line is greedy with other container types, must be last! | |
//: T extends undefined ? undefined | |
//: T extends null ? null | |
//: T extends boolean ? boolean | |
//: T extends string ? string | |
//: T extends number ? number | |
//: T extends Function ? Function | |
: T extends ImmutablePrimitive ? T // any matches by being distributive!! This makes the whole type "ANY" | |
: never | |
type I = Immutable<T> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment