Skip to content

Instantly share code, notes, and snippets.

@Callek
Created December 9, 2022 21:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Callek/0c5f8da2de7d892fa93afcbe4dfe3bfe to your computer and use it in GitHub Desktop.
Save Callek/0c5f8da2de7d892fa93afcbe4dfe3bfe to your computer and use it in GitHub Desktop.
[callek@lyra type-fest]$ rg -i -C6 Error
readme.md
160-
161- submitContactForm({
162- email: 'ex@mple.com',
163- message: 'Hi! Could you tell me more about…',
164- });
165-
166: // TypeScript error: missing property 'message'
167- submitContactForm({
168- email: 'ex@mple.com',
169- });
170- ```
171- </details>
172-
--
179- [Playground](https://typescript-play.js.org/?target=6#code/AQ4UwOwVwW2AZA9gc3mAbmANsA3gKFCOAHkAzMgGkOJABEwAjKZa2kAUQCcvEu32AMQCGAF2FYBIAL4BufDRABLCKLBcywgMZgEKZOoDCiCGSXI8i4hGEwwALmABnUVxXJ57YFgzZHSVF8sT1BpBSItLGEnJz1kAy5LLy0TM2RHACUwYQATEywATwAeAITjU3MAPnkrCJMXLigtUT4AClxgGztKbyDgaX99I1TzAEokr1BRAAslJwA6FIqLAF48TtswHp9MHDla9hJGACswZvmyLjAwAC8wVpm5xZHkUZDaMKIwqyWXYCW0oN4sNlsA1h0ug5gAByACyBQAggAHJHQ7ZBIFoXbzBjMCz7OoQP5YIaJNYQMAAdziCVaALGNSIAHomcAACoFJFgADKWjcSNEwG4vC4ji0wggEEQguiTnMEGALWAV1yAFp8gVgEjeFyuKICvMrCTgVxnst5jtsGC4ljsPNhXxGaAWcAAOq6YRXYDCRg+RWIcA5JSC+kWdCepQ+v3RYCU3RInzRMCGwlpC19NYBW1Ye08R1AA)
180-
181- ```ts
182- enum LogLevel {
183- Off,
184- Debug,
185: Error,
186- Fatal
187- };
188-
189- interface LoggerConfig {
190- name: string;
191- level: LogLevel;
--
204- name: 'MyApp',
205- level: LogLevel.Debug
206- };
207-
208- const logger = new Logger(config);
209-
210: // TypeScript Error: cannot assign to read-only property.
211: logger.config.level = LogLevel.Error;
212-
213- // We are able to edit config variable as we please.
214: config.level = LogLevel.Error;
215- ```
216- </details>
217-
218-- [`Pick<T, K>`](https://github.com/Microsoft/TypeScript/blob/2961bc3fc0ea1117d4e53bc8e97fa76119bc33e3/src/lib/es5.d.ts#L1422-L1427) - From `T`, pick a set of properties whose keys are in the union `K`.
219- <details>
220- <summary>
--
287- firstName: 'John',
288- lastName: 'Doe',
289- yearsOfExperience: 0
290- });
291-
292- // `Record` forces you to initialize all of the property keys.
293: // TypeScript Error: "tech-lead" property is missing
294- const teamEmpty: Record<MemberPosition, null> = {
295- intern: null,
296- developer: null,
297- };
298- ```
299- </details>
--
406-
407- serverBuilder
408- .port('8000') // portNumber = '8000'
409- .port(null) // portNumber = 8000
410- .port(3000); // portNumber = 3000
411-
412: // TypeScript error
413- serverBuilder.portNumber = null;
414- ```
415- </details>
416-
417-- [`Parameters<T>`](https://github.com/Microsoft/TypeScript/blob/2961bc3fc0ea1117d4e53bc8e97fa76119bc33e3/src/lib/es5.d.ts#L1451-L1454) - Obtain the parameters of a function type in a tuple.
418- <details>
source/merge-exclusive.d.ts
26-
27-exclusiveOptions = {exclusive1: true};
28-//=> Works
29-exclusiveOptions = {exclusive2: 'hi'};
30-//=> Works
31-exclusiveOptions = {exclusive1: true, exclusive2: 'hi'};
32://=> Error
33-```
34-*/
35-export type MergeExclusive<FirstType, SecondType> =
36- (FirstType | SecondType) extends object ?
37- (Without<FirstType, SecondType> & SecondType) | (Without<SecondType, FirstType> & FirstType) :
38- FirstType | SecondType;
source/readonly-deep.d.ts
23-export default data;
24-
25-// test.ts
26-import data from './main';
27-
28-data.foo.push('bar');
29://=> error TS2339: Property 'push' does not exist on type 'readonly string[]'
30-```
31-*/
32-export type ReadonlyDeep<T> = T extends Primitive | ((...arguments: any[]) => unknown)
33- ? T
34- : T extends ReadonlyMap<infer KeyType, infer ValueType>
35- ? ReadonlyMapDeep<KeyType, ValueType>
source/require-exactly-one.d.ts
19- text: () => string;
20- json: () => string;
21- secure: boolean;
22-};
23-
24-const responder: RequireExactlyOne<Responder, 'text' | 'json'> = {
25: // Adding a `text` key here would cause a compile error.
26-
27- json: () => '{"message": "ok"}',
28- secure: true
29-};
30-```
31-*/
license-cc0
105- surrendered, licensed or otherwise affected by this document.
106- b. Affirmer offers the Work as-is and makes no representations or
107- warranties of any kind concerning the Work, express, implied,
108- statutory or otherwise, including without limitation warranties of
109- title, merchantability, fitness for a particular purpose, non
110- infringement, or the absence of latent or other defects, accuracy, or
111: the present or absence of errors, whether or not discoverable, all to
112- the greatest extent permissible under applicable law.
113- c. Affirmer disclaims responsibility for clearing rights of other persons
114- that may apply to the Work or any use thereof, including without
115- limitation any person's Copyright and Related Rights in the Work.
116- Further, Affirmer disclaims responsibility for obtaining any necessary
117- consents, permissions or other rights required for any use of the
test-d/require-at-least-one.ts
1:import {expectType, expectError} from 'tsd';
2-import {RequireAtLeastOne} from '..';
3-
4-type SystemMessages = {
5- default: string;
6-
7- macos?: string;
--
15-const test = (_: ValidMessages): void => {};
16-
17-test({macos: 'hey', default: 'hello'});
18-test({linux: 'sup', default: 'hello', optional: 'howdy'});
19-test({macos: 'hey', linux: 'sup', windows: 'hi', default: 'hello'});
20-
21:expectError(test({}));
22:expectError(test({macos: 'hey'}));
23:expectError(test({default: 'hello'}));
24-
25-declare const atLeastOneWithoutKeys: RequireAtLeastOne<{a: number; b: number}>;
26-expectType<{a: number; b?: number} | {a?: number; b: number}>(atLeastOneWithoutKeys);
test-d/require-exactly-one.ts
1:import {expectType, expectError} from 'tsd';
2-import {RequireExactlyOne} from '..';
3-
4-type SystemMessages = {
5- default: string;
6-
7- macos: string;
--
13-type ValidMessages = RequireExactlyOne<SystemMessages, 'macos' | 'linux'>;
14-const test = (_: ValidMessages): void => {};
15-
16-test({macos: 'hey', default: 'hello'});
17-test({linux: 'sup', optional: 'howdy', default: 'hello'});
18-
19:expectError(test({}));
20:expectError(test({macos: 'hey', linux: 'sup', default: 'hello'}));
21-
22-declare const oneWithoutKeys: RequireExactlyOne<{a: number; b: number}>;
23-expectType<{a: number} | {b: number}>(oneWithoutKeys);
24:expectError(expectType<{a: number; b: number}>(oneWithoutKeys));
test-d/merge-exclusive.ts
1:import {expectType, expectError} from 'tsd';
2-import {MergeExclusive} from '..';
3-
4-interface BaseOptions {
5- option?: string;
6-}
7-
--
22- exclusiveVariation1
23-);
24-expectType<{option?: string; exclusive1?: string; exclusive2: number}>(
25- exclusiveVariation2
26-);
27-
28:expectError<Options>({exclusive1: true, exclusive2: 1});
test-d/partial-deep.ts
1:import {expectType, expectError} from 'tsd';
2-import {PartialDeep} from '..';
3-
4-const foo = {
5- baz: 'fred',
6- bar: {
7- function: (_: string): void => {},
--
22- readonlyTuple: ['foo'] as const
23- }
24-};
25-
26-let partialDeepFoo: PartialDeep<typeof foo> = foo;
27-
28:expectError(expectType<Partial<typeof foo>>(partialDeepFoo));
29-const partialDeepBar: PartialDeep<typeof foo.bar> = foo.bar;
30-expectType<typeof partialDeepBar | undefined>(partialDeepFoo.bar);
31-expectType<((_: string) => void) | undefined>(partialDeepFoo.bar!.function);
32-expectType<object | undefined>(partialDeepFoo.bar!.object);
33-expectType<string | undefined>(partialDeepFoo.bar!.string);
34-expectType<number | undefined>(partialDeepFoo.bar!.number);
test-d/set-optional.ts
1:import {expectType, expectError} from 'tsd';
2-import {SetOptional} from '..';
3-
4-// Update one required and one optional to optional.
5-declare const variation1: SetOptional<{a: number; b?: string; c: boolean}, 'b' | 'c'>;
6-expectType<{a: number; b?: string; c?: boolean}>(variation1);
7-
--
12-// Three optional remain optional.
13-declare const variation3: SetOptional<{a?: number; b?: string; c?: boolean}, 'a' | 'b' | 'c'>;
14-expectType<{a?: number; b?: string; c?: boolean}>(variation3);
15-
16-// Fail if type changes even if optional is right.
17-declare const variation4: SetOptional<{a: number; b?: string; c: boolean}, 'b' | 'c'>;
18:expectError<{a: boolean; b?: string; c?: boolean}>(variation4);
test-d/set-required.ts
1:import {expectType, expectError} from 'tsd';
2-import {SetRequired} from '..';
3-
4-// Update one required and one optional to required.
5-declare const variation1: SetRequired<{a?: number; b: string; c?: boolean}, 'b' | 'c'>;
6-expectType<{a?: number; b: string; c: boolean}>(variation1);
7-
--
12-// Three required remain required.
13-declare const variation3: SetRequired<{a: number; b: string; c: boolean}, 'a' | 'b' | 'c'>;
14-expectType<{a: number; b: string; c: boolean}>(variation3);
15-
16-// Fail if type changes even if optional is right.
17-declare const variation4: SetRequired<{a?: number; b: string; c?: boolean}, 'b' | 'c'>;
18:expectError<{a?: boolean; b: string; c: boolean}>(variation4);
test-d/readonly-deep.ts
1:import {expectType, expectError} from 'tsd';
2-import {ReadonlyDeep} from '../source/readonly-deep';
3-
4-const data = {
5- object: {
6- foo: 'bar'
7- },
--
23-};
24-
25-const readonlyData: ReadonlyDeep<typeof data> = data;
26-
27-readonlyData.fn('foo');
28-
29:expectError(readonlyData.string = 'bar');
30-expectType<{readonly foo: string}>(readonlyData.object);
31-expectType<string>(readonlyData.string);
32-expectType<number>(readonlyData.number);
33-expectType<boolean>(readonlyData.boolean);
34-expectType<symbol>(readonlyData.symbol);
35-expectType<null>(readonlyData.null);
test-d/class.ts
1:import {expectError} from 'tsd';
2-import {Class} from '..';
3-
4-class Foo {
5- constructor(x: number, y: any) {
6- console.log(x, y);
7- }
--
12-
13-function fn(Cls: Class<Foo>): Foo {
14- return new Cls(1, '', 123);
15-}
16-
17-function fn2(Cls: Class<Foo, [number, number]>): Foo {
18: expectError(new Cls(1, ''));
19- return new Cls(1, 2);
20-}
21-
22-fn(Foo);
23-fn2(Foo);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment