类型体操刷题系列(十六)— StartWith/EndsWith/PartialByKeys

497 阅读1分钟

目的

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

ts 类型体操 github 我的解答

题目大纲

  1. Medium Start With
  2. Medium Ends With
  3. Medium Partial By Keys

01. Medium Start With

题目要求

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

type cases = [
  Expect<Equal<StartsWith<'abc', 'ac'>, false>>,
  Expect<Equal<StartsWith<'abc', 'ab'>, true>>,
  Expect<Equal<StartsWith<'abc', 'abcd'>, false>>,
]

我的答案

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

知识点

  1. 字符串类型通过infer的推断

2. Medium Ends With

题目要求

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

type cases = [
  Expect<Equal<EndsWith<'abc', 'bc'>, true>>,
  Expect<Equal<EndsWith<'abc', 'abc'>, true>>,
  Expect<Equal<EndsWith<'abc', 'd'>, false>>,
]

我的解答

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

3. Medium Partial By Keys

题目要求

import { Equal, Expect, ExpectFalse, NotEqual } from "@type-challenges/utils";

interface User {
  name: string;
  age: number;
  address: string;
}

interface UserPartialName {
  name?: string;
  age: number;
  address: string;
}

interface UserPartialNameAndAge {
  name?: string;
  age?: number;
  address: string;
}

type cases = [
  Expect<Equal<PartialByKeys<User, "name">, UserPartialName>>,
  Expect<Equal<PartialByKeys<User, "name" | "unknown">, UserPartialName>>,
  Expect<Equal<PartialByKeys<User, "name" | "age">, UserPartialNameAndAge>>,
  Expect<Equal<PartialByKeys<User>, Partial<User>>>
];

我的解答

type RealKey<K> = K extends K ? K : never;

type RealObj<T extends object, K extends keyof T = keyof T> = {
  [key in RealKey<K>]: T[K];
};

type PartialByKeys<
  T extends object,
  K extends string = "",
  R extends keyof T = keyof T,
  V extends object = {
    [key in Exclude<RealKey<R>, K>]: T[key];
  } & {
    [key in K extends RealKey<keyof T> ? K : never]?: T[key];
  }
> = K extends ""
  ? {
      [key in keyof V]?: V[key];
    }
  : {
      [key in keyof V]: V[key];
    };

知识点

  1. 两个 &连接的对象需要重新遍历一下,这样才能真正组合成一个对象的来行
  2. 48 题中提到的相关点