Last active
May 5, 2022 18:40
-
-
Save jfet97/e446840461985534b41e66ddaa33393f to your computer and use it in GitHub Desktop.
as const without as const
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
// is always the extends keyword that makes the difference, enabling the narrow infering | |
type Narrowable = string | number | boolean | symbol | undefined | null | void; | |
declare function wrongKeepLiteralTypes(x: Narrowable): Narrowable; | |
declare function keepLiteralTypes<T extends Narrowable>(x: T): T; | |
wrongKeepLiteralTypes(1); // Narrowable | |
keepLiteralTypes(1); // 1 | |
// | |
// preserve tuple types by using the empty tuple (or using [...T]) | |
declare function numberTuple<T extends [] | number[]>(t: T): T; | |
numberTuple([1, 2, 3]); // is [number, number, number] instead of number[] | |
// N is not inferred because it isn't in the arguments list, but the way TypeScript will infer T | |
// has changed because N is used into the 'extends' clause of T | |
declare function narrowableTuple<N extends Narrowable, T extends [] | N[]>(t: T): T; | |
narrowableTuple([1, 2, 3]); // we got [1, 2, 3] | |
// | |
// same power as 'as const', but no readonly | |
// 'N' is for literals | |
// 'object' is needed to allow properties that are objects themselves, including 'N[]' and 'any[]' | |
// '[]' is for tuple > array | |
// '{ [k: PropertyKey]: T }' is for nested structures | |
declare function asConstNoReadonly<N extends Narrowable, T extends N | object | [] | { [k: PropertyKey]: T }>(x: T): T; | |
asConstNoReadonly(123) // 123 | |
asConstNoReadonly(["this", "is", "a"]) // ["this", "is", "a"] | |
asConstNoReadonly(["this", "is", "a", { a: 7 }]) // ["this", "is", "a", { a: 7; }] | |
asConstNoReadonly({ a: 7 }) // { a: 7; } | |
asConstNoReadonly({ a: { b: 43, c: ["this", "is", "a", "tuple", { oh: "yes"} ] } }) | |
// { a: { b: 43; c: ["this", "is", "a", "tuple", { oh: "yes"; }]; }; } | |
// only objects | |
declare function asConst<N extends Narrowable, T extends { [k: PropertyKey]: N | [] | T | {} }>(x: T): T; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment