Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

type-challenges solution ( medium ) #43

Open
jiangshanmeta opened this issue Sep 6, 2021 · 0 comments
Open

type-challenges solution ( medium ) #43

jiangshanmeta opened this issue Sep 6, 2021 · 0 comments

Comments

@jiangshanmeta
Copy link
Owner

jiangshanmeta commented Sep 6, 2021

type-challenges

原项目地址

2・Get Return Type

type MyReturnType<T extends (...arg:any)=>any> = T extends (...arg:any)=>infer U?U:never;

3・Omit

type MyOmit<T, K extends keyof T> = Pick<T,Exclude<keyof T,K>>

8・Readonly 2

type MyReadonly2<T, K extends keyof T = keyof T> = Readonly<Pick<T,K>> & Omit<T,K>

9・Deep Readonly

type DeepReadonly<T extends object> = {
  readonly [K in keyof T]:T[K] extends object? T[K] extends Function?T[K]: DeepReadonly<T[K]>:T[K]
}

10・Tuple to Union

type TupleToUnion<T extends readonly any[]> = T[number]

12・Chainable Options

type Chainable<T={}> = {
  option<K extends string,U>(key: K, value: U): Chainable<T & {[P in K]:U}>
  get(): T
}

15・Last of Array

type Last<T extends any[]> = T extends [...any,infer U]?U:never;

16・Pop

type Pop<T extends any[]> = T extends [...infer U,any]?U:never;

20・Promise.all

type UnwrapPromise<T> = T extends Promise<infer U>?U:T;
declare function PromiseAll<T extends any[]>(values: readonly [...T]): Promise<{
  [K in keyof T]:UnwrapPromise<T[K]>
}>

62・Type Lookup

type LookUp<U extends {type:string}, T extends U['type']> = U extends {type:T}?U:never;

106・Trim Left

type Space = ' ' | '\n' | '\t'
type TrimLeft<S extends string> = S extends `${Space}${infer T}`?TrimLeft<T>:S

108・Trim

type Space = ' ' | '\n' | '\t'
type TrimLeft<S extends string> = S extends `${Space}${infer T}`?TrimLeft<T>:S
type TrimRight<S extends string> = S extends `${infer T}${Space}`?TrimRight<T>:S;

type Trim<S extends string> = TrimRight<TrimLeft<S>>

110・Capitalize

type Capitalize<S extends string> = S extends `${infer F}${infer R}`?`${Uppercase<F>}${R}`:S

116・Replace

type Replace<S extends string, From extends string, To extends string> = From extends ''?S:S extends `${infer F}${From}${infer L}`?`${F}${To}${L}`:S;

119・ReplaceAll

type ReplaceAll<S extends string, From extends string, To extends string> = From extends ''?S:S extends `${infer F}${From}${infer L}`?`${F}${To}${ReplaceAll<L,From,To>}`:S

191・Append Argument

type AppendArgument<Fn extends (...args:any)=>any, A> = (...a:[...Parameters<Fn>,A])=>ReturnType<Fn>

296・Permutation

type isNever<T> = [T] extends [never]?true:false;
type Permutation<T extends string,R extends string[] = [], K = T > = isNever<T> extends true?
  R:
  K extends T? Permutation<Exclude<T,K>,[...R,K]>:R

298・Length of String

type LengthOfString<S extends string,L extends string[]=[]> = S extends `${infer A}${infer O}`?LengthOfString<O,[...L,A]>:L['length']

459・Flatten

type Flatten<T extends any[]> = T extends [infer F,...infer R]? F extends any[]? [...Flatten<F>,...Flatten<R>]:[F,...Flatten<R>] : T;

527・Append to object

type AppendToObject<T,U extends string,V> = {
  [K in (keyof T) | U]:K extends keyof T?T[K]:V
}

529・Absolute

type Absolute<T extends number | string | bigint> = `${T}` extends `-${infer U}`?`${U}`:`${T}`

531・String to Union

type StringToUnion<T extends string> = T extends `${infer F}${infer O}`?F | StringToUnion<O>:never

599・Merge

type Merge<F, S> = {
  [K in ( (keyof F) | (keyof S))]:K extends keyof S?S[K]:(K extends keyof F?F[K]:never)
}

610・CamelCase

type CamelCase<S extends string> = S extends `${infer F}-${infer T}${infer R}`?
  T extends '-'?
    `${F}-${CamelCase<`${T}${R}`>}`
    :
    `${F}${T extends Uppercase<T>?`-${T}`:Uppercase<T>  }${CamelCase<R>}`:S;

612・KebabCase

type KebabCase<S extends string,P extends string = ''> = 
  S extends `${infer F}${infer O}`?
    F extends Lowercase<F>?
      KebabCase<O,`${P}${F}`>
      :P extends ''? KebabCase<O,Lowercase<F>>:KebabCase<O,`${P}-${Lowercase<F>}`>
  :P

645・Diff

type Diff<O,O1> = {
  [K in Exclude<keyof O,keyof O1> |  Exclude<keyof O1,keyof O>]:K extends keyof O?O[K]:K extends keyof O1?O1[K]:never
}

949・AnyOf

type falsy = '' | false | 0| [] | {[x:string]:never};
type AnyOf<T extends readonly any[]> = T[number] extends falsy?false:true

1042・IsNever

type IsNever<T> = [T] extends [never]?true:false

1097・IsUnion

type IsUnion<T,U = T> = T extends U ?
  [U] extends [T]?false:true
  :never

1130・ReplaceKeys

type ReplaceKeys<U, T extends string, Y > = {
  [K in keyof U]:K extends T? (K extends keyof Y?Y[K]:never) : U[K] 
}

1367・Remove Index Signature

// 索引类型特点 不是具体的字面量类型 而是 string number
// 利用never类型过滤
type OmitIndexSignature<T> = 
  string extends T ? 
  never :
  number extends T?
    never:T
// https://github.com/zhongsp/TypeScript/blob/dev/zh/release-notes/typescript-4.1.md#%E5%9C%A8%E6%98%A0%E5%B0%84%E7%B1%BB%E5%9E%8B%E4%B8%AD%E6%9B%B4%E6%94%B9%E6%98%A0%E5%B0%84%E7%9A%84%E9%94%AE 
// 在映射类型中更改映射的键
type RemoveIndexSignature<T> = {
  [K in keyof T as OmitIndexSignature<K>]:T[K]
}

1978・Percentage Parser

type ParseRest<T extends string> = T extends `${infer U}%`?[U,'%']:[T,'']
type PercentageParser<A extends string> = 
  A extends `${infer F}${infer R}`?
    F extends '+' | '-'?
      [F,...ParseRest<R>]
      :
      ['',...ParseRest<A>]
  :['','','']

2070・Drop Char

type DropChar<S extends string, C extends string> = S extends `${infer A}${C}${infer B}`?
  DropChar<`${A}${B}`,C>
  :S

2257・MinusOne

type Make10Array<T extends any[]> = [
  ...T,
  ...T,
  ...T,
  ...T,
  ...T,
  ...T,
  ...T,
  ...T,
  ...T,
  ...T,
]
type oneDigitNum = '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9'
type Make1Array<T extends string,L extends any[] = []> = `${L['length']}` extends T? L:Make1Array<T,[1,...L]>
type MakeArray<T extends string,L extends any[] = []> = T extends `${infer F}${infer R}`? MakeArray< R,[
  ...Make10Array<L>,
  ...Make1Array<F>
]> : L

type Pop<T extends any[]> = T extends [...infer R, infer L]?R:[]

type MinusOne<T extends number> = Pop<MakeArray<`${T}`>>['length']

2595・PickByType

解法一 利用 Key Remapping in Mapped Types

type FilterKey<V,U,K> = V extends U?K:never;

type PickByType<T, U> = {
  [K in keyof T as FilterKey<T[K],U,K>]:T[K]
}

解法二:

type PickByType<T, U> = {
  [K in keyof T as (T[K] extends U?K:never)]:T[K]
}

2688・StartsWith

type StartsWith<T extends string, U extends string> = T extends `${U}${string}`?true:false

2693・EndsWith

type EndsWith<T extends string, U extends string> = T extends `${string}${U}`?true:false;

2757・PartialByKeys

// 为什么需要这个Copy https://github.com/microsoft/TypeScript/blob/main/doc/spec-ARCHIVED.md#3.11.2
// Two types are considered identical when
// they are intersection types with identical sets of constituent types
// 一个是交叉类型的 一个不是交叉类型 他们不是identical 虽然可能是类型兼容互相assignable

type Copy<T> = {
  [K in keyof T]:T[K]
}
type PartialByKeys<T , K extends keyof any = keyof T> = Copy<Partial<Pick<T,Extract<keyof T, K>>> & Omit<T,K>>

2759・RequiredByKeys

type Copy<T> = {
  [K in keyof T]:T[K]
}
type RequiredByKeys<T , K extends keyof any = keyof T> = Copy<Required<Pick<T,Extract<keyof T,K>>> & Omit<T,Extract<keyof T,K>>>

2793・Mutable

type Mutable<T> = {
  -readonly [K in keyof T]:T[K]
}

2852・OmitByType

type OmitByType<T, U> = {
  [K in keyof T as (T[K] extends U? never:K)]:T[K]
}

2946・ObjectEntries

type ObjectEntries<T,U = Required<T>> = {
  [K in keyof U]:[K,U[K]]
}[keyof U]

3062・Shift

type Shift<T extends any[]> = T extends [any,...infer U]?U:never 

3188・Tuple to Nested Object

type TupleToNestedObject<T, U> = T extends [infer F,...infer R]?
  {
    [K in F&string]:TupleToNestedObject<R,U>
  }
  :U

3192・Reverse

type Reverse<T> = T extends [infer F,...infer M,infer L]?
  [L,...Reverse<M>,F]
  :T

3196・Flip Arguments

type Reverse<T> = T extends [infer F,...infer M,infer L]?
  [L,...Reverse<M>,F]
  :T
type FlipArguments<T extends (...args:any)=>any > = T extends (...args:infer P)=>infer R? (...args:Reverse<P>)=>R : never

3243・FlattenDepth

type FlattenDepth<T extends any[], C extends number = 1, U extends any[] = []> = T extends [infer F,...infer R]?
  F extends any[]?
    U['length'] extends C?
      [F, ...FlattenDepth<R, C, U>]
      :[...FlattenDepth<F, C, [0,...U]>,...FlattenDepth<R, C, U>]
    :[F,...FlattenDepth<R, C, U>]

  : T;

3326・BEM style string

type BEM<B extends string, E extends string[], M extends string[]> = `${B}${E['length'] extends 0? '':`__${E[number]}`}${M['length'] extends 0? '':`--${M[number]}`}`

3376・InorderTraversal 🤓

interface TreeNode {
  val: number;
  left: TreeNode | null;
  right: TreeNode | null;
}
type InorderTraversal<T extends TreeNode | null, U extends TreeNode = NonNullable<T>> = 
  T extends null?
    []
    :[...InorderTraversal<U['left']>,U['val'],...InorderTraversal<U['right']>]

4179・Flip

type Flip<T extends Record<string,string | number | boolean>> = {
  [K in keyof T as `${T[K]}`]:K
}

4182・Fibonacci Sequence

type Fibonacci<T extends number,C extends any[] = [1,1,1],A extends any[] = [1],B extends  any[] = [1]> = 
  T extends 1? 
    1:
    T extends 2?
    1:
      C['length'] extends T?
        [...A,...B]['length']
        :Fibonacci<T,[1,...C],B,[...A,...B]>

4260・AllCombinations

type Combination<
  S extends string,
  U extends string='',
  K = S
> = 
[S] extends [never]?
  U: 
  K extends S? 
    Combination<Exclude<S,K>,U | `${U}${K}`>
    :U

type String2Union<S extends string,R extends string = never> = S extends `${infer F}${infer L}`? String2Union<L,R | F>:R


type AllCombinations<S extends string> = Combination<String2Union<S>>

4425・Greater Than

type GreaterThan<T extends number, U extends number,TL extends number[] = [],UL extends number[] = []> = 
  T extends U ?
    false:
    UL['length'] extends U?
      true :
      TL['length'] extends T?
        false:
        GreaterThan<T,U,[0,...TL],[0,...UL]>

4471・Zip

type Zip<T extends any[],U extends any[]> = 
  T extends [infer TF,...infer TR]?
    U extends [infer UF,...infer UR]?
      [[TF,UF],...Zip<TR,UR>]
    :[]
  :[]

4484・IsTuple

type IsTuple<T> = 
  T extends readonly any[]?
    number extends T['length']?false:true
  :false

4499・Chunk

type Chunk<T extends any[],C extends number,S extends any[] = []> = 
  S['length'] extends C?
    [S,...Chunk<T,C>]
    : T extends [infer F,...infer R]?
        Chunk<R,C,[...S,F]>
      : S['length'] extends 0? []: [S]

4518・Fill

type GreaterThan<T extends number, U extends number,TL extends number[] = [],UL extends number[] = []> = 
  T extends U ?
    false:
    UL['length'] extends U?
      true :
      TL['length'] extends T?
        false:
        GreaterThan<T,U,[0,...TL],[0,...UL]>

type FillNormal<
  T extends unknown[],
  N,
  Start extends number = 0,
  End extends number = T['length'],
  R extends unknown[] = [],
  I extends boolean = false
> = T extends [infer F,...infer L]?
      R['length'] extends End? [...R,...T]:
            R['length'] extends Start? FillNormal<L,N,Start,End,[...R,N],true>
              : I extends true ? FillNormal<L,N,Start,End,[...R,N],true>
                  : FillNormal<L,N,Start,End,[...R,F],false>
    : R


type Fill<
  T extends unknown[],
  N,
  Start extends number = 0,
  End extends number = T['length'],
> = GreaterThan<End,Start> extends true?
      FillNormal<T,N,Start,End>:T

4803・Trim Right

type Separator = ' ' | '\n' | '\t';

type TrimRight<S extends string> = S extends `${infer R}${Separator}`? TrimRight<R>:S;

5117・Without

type Includes<
  T extends any[],
  U
> = 
T extends [infer F,...infer R]? 
  F extends U? 
    true:Includes<R,U>
  :false

type WithoutMulti<
  T extends any[],
  U extends any[],
  R extends any[] = []
> = 
T extends [infer F,...infer L]?
  Includes<U,F> extends true? WithoutMulti<L,U,R>:WithoutMulti<L,U,[...R,F]>
  : R

type Without<T extends any[], U extends (number | number[] )> = U extends number[]? WithoutMulti<T,U>:WithoutMulti<T,[U]>

5140・Trunc

type Trunc<T extends string | number> = `${T}` extends `${infer F}.${infer R}`? F: `${T}`

5153・IndexOf

type IndexOf<
  T, 
  U,
  L extends any[] = []
> = 
  T extends [infer F,...infer R]?
    U extends F? L['length']:IndexOf<R,U,[1,...L]>
  : -1

5310・Join

type Join<
  T extends any[], 
  U extends string | number,
  R extends string = ''
> = 
  T extends [infer F,...infer L]?
    L['length'] extends 0?
      `${R extends ''?'':`${R}${U}`}${F&string}`
      :Join<L,U,`${R extends ''?'':`${R}${U}`}${F&string}`>
  :R

5317・LastIndexOf

type LastIndexOf<T extends any[], U> = T extends [...infer I,infer L]? L extends U?I['length']: LastIndexOf<I,U> : -1;

5360・Unique

type Unique<T extends any[],R extends any[] = []> = T extends [infer F,...infer L]? Unique<L,F extends R[number]? R:[...R,F] >:R

5821・MapTypes

type MapTypes<T, R extends {mapFrom:any,mapTo:any},U extends {mapFrom:any,mapTo:any} = R> = {
  [K in keyof T]:U extends R? (T[K] extends R['mapFrom']?  (T[K] extends U['mapFrom']?U['mapTo']:never ) :T[K]   ):never
}

7258・ObjectKeyPaths

type GenNode<K extends string | number,IsRoot extends boolean> = IsRoot extends true? `${K}`: `.${K}` | (K extends number? `[${K}]` | `.[${K}]`:never)

type ObjectKeyPaths<
  T extends object,
  IsRoot extends boolean = true,
  K extends keyof T = keyof T
> = 
K extends string | number ?
  GenNode<K,IsRoot> | (T[K] extends object? `${GenNode<K,IsRoot>}${ObjectKeyPaths<T[K],false>}`:never)
  :never;

7544・Construct Tuple

type ConstructTuple<L extends number,R extends unknown[]= []> = R['length'] extends L? R: ConstructTuple<L,[...R,unknown]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant