类型体操刷题系列(十一)— Absolute/StingToUnion/Merge

296 阅读1分钟

目的

Github上的类型体操,让你写出更加优雅的TS类型定义,以及探寻TS中我们不熟悉的只是,让我们开始TS的类型挑战把~2022希望通过更文的方式来督促自己学习,每日三题,坚持日更不断~~

ts 类型体操 github 我的解答

题目大纲

  1. Medium Absolute
  2. Medium StingToUnion
  3. Medium Merge

01. Length Of String

题目要求

import { Equal, Expect } from '@type-challenges/utils'

type cases = [
  Expect<Equal<Absolute<0>, '0'>>,
  Expect<Equal<Absolute<-0>, '0'>>,
  Expect<Equal<Absolute<10>, '10'>>,
  Expect<Equal<Absolute<-5>, '5'>>,
  Expect<Equal<Absolute<'0'>, '0'>>,
  Expect<Equal<Absolute<'-0'>, '0'>>,
  Expect<Equal<Absolute<'10'>, '10'>>,
  Expect<Equal<Absolute<'-5'>, '5'>>,
  Expect<Equal<Absolute<-1_000_000n>, '1000000'>>,
  Expect<Equal<Absolute<9_999n>, '9999'>>,
]

我的答案

type Absolute<T extends string | number | bigint> = (
  T extends any ? `${T}` : never
) extends `-${infer P}`
  ? P
  : `${T}`;

知识点

  1. 使用模板字符串的方式,将数字变为字符串类型。
  2. extendsinfer推断的时候,如果我们想让其满足某个定义的模式,直接通过模板字符串来做就行,这里的P会变成一个负数的数字部分了

2. Medium Sting To Union

题目要求

import { Equal, Expect } from '@type-challenges/utils'

type cases = [
  Expect<Equal<StringToUnion<"">, never>>,
  Expect<Equal<StringToUnion<"t">, "t">>,
  Expect<Equal<StringToUnion<"hello">, "h" | "e" | "l" | "l" | "o">>,
  Expect<Equal<StringToUnion<"coronavirus">, "c" | "o" | "r" | "o" | "n" | "a" | "v" | "i" | "r" | "u" | "s">>,

我的解答

type StringToUnion<
  T extends string,
  R extends object = {}
> = T extends `${infer P}${infer K}`
  ? P extends ""
    ? keyof R
    : StringToUnion<K, R & { [key in P]: 1 }>
  : keyof R;

知识点

  1. 需要转成联合类型可以使用keyof object
  2. 利用创造的泛型来接收参数

3. Medium Merge

题目要求

import { Equal, Expect } from '@type-challenges/utils'

type Foo = {
  a: number;
  b: string;
};
type Bar = {
  b: number;
  c: boolean;
};

type cases = [
  Expect<Equal<Merge<Foo, Bar>, {
	a: number;
	b: number;
	c: boolean;
  }>>
]

type merge = Merge<Foo, Bar>

我的解答

type MergeObj<F extends object, S extends object> = {
  [K in keyof S]: S[K];
} & {
  [K in Exclude<keyof F, keyof S>]: F[K];
};

type Merge<
  F extends object,
  S extends object,
  R extends object = MergeObj<F, S>
> = {
  [K in keyof R]: R[K];
};

知识点

  1. 当两个对象需要合并的时候需要两步:1. 先将两个对象用 &连接 2. 再遍历一次这个对象就可以了。