Skip to content

Type Challenges

About 509 wordsAbout 2 min

2022-11-29

Under construction...

Introduction

type-challenges is an open source project that allows you to better understand the typescript type system.

This note records my personal challenges in solving this project, the problem-solving ideas I used, the answers, and the relevant typescript knowledge points.

According to the difficulty of the questions in type-challenges, they are divided into five levels of difficulty:

  • Warm-up
  • Easy
  • Medium
  • Hard
  • Hell

Please read this note from top to bottom to better understand the challenges of type-challenges.

If you are a beginner, or just want to use typescript in your daily work, then it is enough to read the questions of Medium difficulty. Starting from Hard difficulty, these questions may be more suitable for developers who want to deeply understand the type design of certain libraries or frameworks, or want to write their own type tools.

VSCode plugin

vsCode plugin type-challenges

The plugin provides all the questions and test cases of the open source project. You can install the plugin in VSCode and answer the questions in VSCode to get good editor type checking help.

Description

In this project, each challenge will be written as a separate article. The content includes:

  • Title: Challenge
  • Solution idea
  • Answer
  • Verification: With the help of typescript twoslash, you can check the type of each answer here and verify whether the result meets the expectation
  • Reference: List the typescript knowledge points required for this challenge

Type tools

During the verification process, the following type tools will be used:

/**
 * Type assertion
 */
export type Expect<T extends true> = T
export type ExpectTrue<T extends true> = T
export type ExpectFalse<T extends false> = T
export type IsTrue<T extends true> = T
export type IsFalse<T extends false> = T

/**
 * Compare whether two types are completely equal
 */
export type Equal<X, Y> = (<T>() => T extends X ? 1 : 2) extends <T>() => T extends Y ? 1 : 2 ? true : false
export type NotEqual<X, Y> = true extends Equal<X, Y> ? false : true

/**
 * Determine if the type is `any`
 */
export type IsAny<T> = 0 extends 1 & T ? true : false
export type NotAny<T> = true extends IsAny<T> ? false : true

export type Debug<T> = { [K in keyof T]: T[K] }
export type MergeInsertions<T> = T extends object ? { [K in keyof T]: MergeInsertions<T[K]> } : T

/**
 * Determine if two types are similar
 */
export type Alike<X, Y> = Equal<MergeInsertions<X>, MergeInsertions<Y>>

/**
 * Determine whether a type inherits from another type
 */
export type ExpectExtends<VALUE, EXPECTED> = EXPECTED extends VALUE ? true : false
/**
 * Determine whether the parameters of a function meet expectations
 */
export type ExpectValidArgs<FUNC extends (...args: any[]) => any, ARGS extends any[]> =
  ARGS extends Parameters<FUNC> ? true : false

/**
 * Convert a union type to an intersection type
 */
export type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never