Skip to content

Instantly share code, notes, and snippets.

@giokaxo
Created August 5, 2022 20:05
Show Gist options
  • Select an option

  • Save giokaxo/70e0610ecf9d45633373098062b201ff to your computer and use it in GitHub Desktop.

Select an option

Save giokaxo/70e0610ecf9d45633373098062b201ff to your computer and use it in GitHub Desktop.
Typescript challenges
// type First<T extends unknown[]> = T extends { length: 0 } ? never : T[0];
// type arr1 = ['a', 'b', 'c']
// type arr2 = [3, 2, 1]
// type head1 = First<arr1> // expected to be 'a'
// type head2 = First<arr2> // expected to be 3
// type Length<T extends unknown[]> = T['length'];
// type tesla = ['tesla', 'model 3', 'model X', 'model Y']
// type spaceX = ['FALCON 9', 'FALCON HEAVY', 'DRAGON', 'STARSHIP', 'HUMAN SPACEFLIGHT']
// type teslaLength = Length<tesla> // expected 4
// type spaceXLength = Length<spaceX> // expected 5
// type MyExclude<T, K> = T extends K ? never : T;
// type From = 'a' | 'b' | 'c';
// type Result = MyExclude<From, 'a'> // 'b' | 'c'
// type If<C extends true | false, T, F> = C extends true ? T : F;
// type A = If<true, 'a', 'b'> // expected to be 'a'
// type B = If<false, 'a', 'b'> // expected to be 'b'
// type Push<T extends unknown[], E> = [...T, E];
// type Result = Push<[1, 2], '3'> // [1, 2, '3']
// type Concat<T extends unknown[], E extends unknown[]> = [...T, ...E];
// type Result = Concat<[1], [2]> // expected to be [1, 2]
// type MyReturnType<T> = T extends (...args: any) => infer R ? R : never;
// const fn = (v: boolean) => {
// if (v)
// return 1
// else
// return 2
// }
// type a = MyReturnType<typeof fn> // should be "1 | 2"
// type MyExclude<T, K> = T extends K ? never : T;
// type MyOmit<T, K extends keyof T> = {
// [U in MyExclude<keyof T, K>]: T[U]
// };
// interface Todo {
// title: string
// description: string
// completed: boolean
// }
// type TodoPreview = MyOmit<Todo, 'description' | 'title'>
// const todo: TodoPreview = {
// completed: false,
// }
// type Last<T extends unknown[]> = T extends [...infer R, infer L] ? L : never;
// type arr1 = ['a', 'b', 'c']
// type arr2 = [3, 2, 1]
// type tail1 = Last<arr1> // expected to be 'c'
// type tail2 = Last<arr2> // expected to be 1
// type Pop<T extends unknown[]> = T extends [...infer R, infer L] ? R : never;
// type arr1 = ['a', 'b', 'c', 'd']
// type arr2 = [3, 2, 1]
// type re1 = Pop<arr1> // expected to be ['a', 'b', 'c']
// type re2 = Pop<arr2> // expected to be [3, 2]
// type Flatten<T extends unknown[]> = T extends [infer L, ...infer R]
// ? L extends unknown[]
// ? [...Flatten<L>, ...Flatten<R>]
// : [L, ...Flatten<R>]
// : T;
// type flatten = Flatten<[1, 2, [3, 4], [[[5]]]]> // [1, 2, 3, 4, 5]
// type AppendToObject<T extends object, K extends string | number | symbol, V> = Record<K | keyof T, V>
// type Test = { id: '1' }
// type Result = AppendToObject<Test, 'value', 4> // expected to be { id: '1', value: 4 }
// type Merge<F, S> = {
// [K in keyof F | keyof S]: K extends keyof S ? S[K] : K extends keyof F ? F[K] : never
// };
// type foo = {
// name: string;
// age: string;
// }
// type coo = {
// age: number;
// sex: string
// }
// type Result = Merge<foo, coo>; // expected to be {name: string, age: number, sex: string}
// type MyCapitalize<T extends string> = T extends `${infer F}${infer R}` ? `${Uppercase<F>}${R}` : never;
// type capitalized = MyCapitalize<'hello world'> // expected to be 'Hello world'
// type ReplaceAll<Word extends string, From extends string, To extends string> =
// Word extends `${infer F}${infer R}` ?
// F extends From ?
// `${To}${ReplaceAll<R, From, To>}` :
// `${F}${ReplaceAll<R, From, To>}` :
// Word;
// type replaced = ReplaceAll<'t y p e s', ' ', ''>; // expected to be 'types'
// type replaced2 = ReplaceAll<'types', 's', 'e'>; // expected to be 'types'
// type replaced3 = ReplaceAll<'test', 't', 'f'>; // expected to be 'types'
// type LengthOfString<S extends string, L extends string[] = []> = S extends `${any}${infer R}`
// ? LengthOfString<R, [...L, string]>
// : L['length']
// type a = LengthOfString<'giorgi'>;
// type Trim<T extends string> = T extends `${infer F}${infer R}${infer E}`
// ? F extends ' '
// ? `${Trim<R>}${Trim<E>}` : `${F}${R}${Trim<E>}`
// : T;
// type Space = ' ' | '\n' | '\t'
// type Trim<S extends string> = S extends `${Space}${infer R}${Space}` | `${Space}${infer R}` | `${infer R}${Space}` ? Trim<R> : S
// type trimmed = Trim<' Hello World '> // expected to be 'Hello World'
// type Reverse<T extends unknown[] = []> = T extends [...infer R, infer L] ? [L, ...Reverse<R>] : T;
// type a = Reverse<['a', 'b']> // ['b', 'a']
// type b = Reverse<['a', 'b', 'c']> // ['c', 'b', 'a']
// type Shift<T extends unknown[]> = T extends [infer F, ...infer R] ? R : T;
// type Result = Shift<[3, 2, 1]> // [2, 1]
// @TODO
// type Without<T extends unknown[], E> = T extends [infer F, ... infer R] ?
// F extends keyof E | E ? Without<R, E> : [F, ...Without<R, E>]
// : T;
// type Res = Without<[1, 2], 1>; // expected to be [2]
// type Res1 = Without<[1, 2, 4, 1, 5], [1, 2]>; // expected to be [4, 5]
// type Res2 = Without<[2, 3, 2, 3, 2, 3, 2, 3], [2, 3]>; // expected to be []
// type Check = 1 extends keyof [1, 2] ? true : false;
// type StartsWith<T extends string, S extends string> = T extends `${S}${infer R}` ? true : false;
// type a = StartsWith<'abc', 'ac'> // expected to be false
// type b = StartsWith<'abc', 'ab'> // expected to be true
// type c = StartsWith<'abc', 'abcd'> // expected to be false
// type CamelCase<S extends string> = S extends `${infer F}${infer R}` ? F extends '_' ? `${Capitalize<CamelCase<R>>}` : `${F}${CamelCase<R>}` : S ;
// type camelCase1 = CamelCase<'hello_world_with_types'> // expected to be 'helloWorldWithTypes'
// type camelCase2 = CamelCase<'HELLO_WORLD_WITH_TYPES'> // expected to be same as previous one
// type KebabCase<S extends string> = S extends `${infer F}${infer R}` ? F extends Uppercase<F> ? `-${Lowercase<F>}${KebabCase<R>}` : `${F}${KebabCase<R>}` : S ;
// type kebabCase1 = KebabCase<'helloWorldWithTypes'> // expected to be 'hello-world-with-types'
// type kebabCase2 = KebabCase<'somethingStrange'> // expected to 'something-strange'
type Zip<T extends unknown[], U extends unknown[]> = ;
type exp = Zip<[1, 2], [true, false]> // expected to be [[1, true], [2, false]]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment