Giter Club home page Giter Club logo

type-challenges's Issues

6 - Simple Vue

✍️ Answers

Name your title starting with the question no you are trying to answer.

For example:
#12 - my one-line solution

type GetComputed<C> = C extends Record<string, (...args: any[]) => any> 
  ? { [S in keyof C]: ReturnType<C[S]> } 
  : never

declare function SimpleVue<D, C, M>(
  options: {
    data: () => D,
    computed: C,
    methods: M,
  } & ThisType<D & M & GetComputed<C>>
): any

Extend Readings

Updates

The challenges get updated with stricter rules in #173, check out #172 for a more proper answer.

14 - First of Array

type First<T extends any[]> = T extends [infer H, ...infer _] ? H : never

6 - Simple Vue

declare function SimpleVue<D, C, M>(options: {
  data: () => D,
  computed: C,
  methods: M,
  // methods: { [k in keyof M]: (this: ThisType<D & C & M>) => M[k] },
} & ThisType<D & { [k in keyof C]: C[k] extends (...args: any[]) => any ? ReturnType<C[k]> : never } & M>): any

16 - Pop

✍️ Answers

Name your title starting with the question no you are trying to answer.

For example:
#12 - my one-line solution

This solution requires TypeScript 4.0

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

3 - Omit<T, K>

type MyOmit<T, K> = {
  [k in Exclude<keyof T, K>]: T[k]
}

7 - Readonly<T>

✍️ Answers

Name your title starting with the question no you are trying to answer.

For example:
#12 - my one-line solution

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

Exclude

Info

difficulty: easy
title: Exclude
#tags: built-in

Question

Implement the built-in Exclude<T, U>

Exclude from T those types that are assignable to U

Template

type MyExclude<T, U> = any

Test Cases

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

type cases = [
    Expect<Equal<MyExclude<"a" | "b" | "c", "a">, Exclude<"a" | "b" | "c", "a">>>,
    Expect<Equal<MyExclude<"a" | "b" | "c", "a" | "b">, Exclude<"a" | "b" | "c", "a" | "b">>>,
    Expect<Equal<MyExclude<string | number | (() => void), Function>, Exclude<string | number | (() => void), Function>>>,
]

15 - Last of Array

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

4 - Pick<T, K>

type MyPick<T, K extends keyof T> = {
  [k in K]: T[k]
}

16 - Pop

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

Get Required

Info

difficulty: hard
title: Get Required
tags: utils, infer

Question

Implement the advanced util type GetRequired<T>, which remains all the required fields

For example

type I = GetRequired<{ foo: number, bar?: string }> // expected to be { foo: number }

Template

type GetRequired<T> = any

Test Cases

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

type cases = [
    Expect<Equal<GetRequired<{ foo: number, bar?: string }>, { foo: number }>>,
    Expect<Equal<GetRequired<{ foo: undefined, bar?: undefined }>, { foo: undefined }>>,
]

5 - Get Readonly Keys

✍️ Answers

Name your title starting with the question no you are trying to answer.

For example:
#12 - my one-line solution

Solution in piotrwitek/utility-types

/**
 * ReadonlyKeys
 * @desc Get union type of keys that are readonly in object type `T`
 * Credit: Matt McCutchen
 * https://stackoverflow.com/questions/52443276/how-to-exclude-getter-only-properties-from-type-in-typescript
 * @example
 *   type Props = { readonly foo: string; bar: number };
 *
 *   // Expect: "foo"
 *   type Keys = ReadonlyKeys<Props>;
 */
export type ReadonlyKeys<T extends object> = {
  [P in keyof T]-?: IfEquals<
    { [Q in P]: T[P] },
    { -readonly [Q in P]: T[P] },
    never,
    P
  >
}[keyof T]

type IfEquals<X, Y, A = X, B = never> = 
  (<T>() => T extends X ? 1 : 2) extends 
  (<T>() => T extends Y ? 1 : 2) ? A : B

Solution provided by @browsnet

type GetReadonlyKeys<T extends Object> = {
  [K in keyof T]: 
    (<S>() => S extends { [Z in K]: T[Z] } ? 2 : 1) extends 
    (<S>() => S extends { -readonly [Z in K]: T[Z] } ? 2: 1) ? never : K
}[keyof T]

Extend Reading

4 - Pick<T, K>

type MyPick<T, K extends keyof T> = { [S in K]: T[S] }

8 - Readonly2<T, K>

✍️ Answers

Name your title starting with the question no you are trying to answer.

For example:
#12 - my one-line solution

type Diff<A, B> = A extends B ? never : A

type MyReadonly2<T, K extends keyof T = keyof T> =
  { readonly [S in K]: T[S] }
  & { [S in Diff<keyof T, K>]: T[S] }

12 - Chainable Options

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

14 - First of Array

✍️ Answers

Name your title starting with the question no you are trying to answer.

For example:
12 - my one-line solution

type First<T extends any[]> = T extends [infer P, ...any[]] ? P : never

Type Lookup

You need to provide a detailed description of your new challenge, either in English or Chinese are acceptable.

Detailed solution/guide is not required, but be sure the challenge is solvable.

Please follow the template and fill the info. A PR will be auto-generated and always reflect on your changes.

Info

Basic info of your challenge questions,

difficulty: medium # medium / hard / extreme
title: Type Lookup
tags: union, map

Question

Sometimes, you may want to lookup for a type in a union to by their attributes.

In this challenge, I would like to have get the couponing type by searching for the common type field in the union Cat | Dog. In other words, I will expect to get Dog for LookUp<Dog | Cat, 'dog'> and Cat for LookUp<Dog | Cat, 'cat'> in the following example.

interface Cat {
  type: 'cat'
  breeds: 'Abyssinian' | 'Shorthair' | 'Curl' | 'Bengal'
}

interface Dog {
  type: 'dog'
  breeds: 'Hound' | 'Brittany' | 'Bulldog' | 'Boxer'
  color: 'brown' | 'white' | 'black'
}

const MyDog = LookUp<Cat | Dog, 'dog'> // expected to be `Dog`

Template

This is the template for challengers to start the coding. Basically, you just need to change the name of your generic/function and leave to implementation any.

type LookUp<U, T> = any

Test Cases

Provide some test cases for your challenge, you can use some utils from @type-challenges/utils for asserting.

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

interface Cat {
  type: 'cat'
  breeds: 'Abyssinian' | 'Shorthair' | 'Curl' | 'Bengal'
}

interface Dog {
  type: 'dog'
  breeds: 'Hound' | 'Brittany' | 'Bulldog' | 'Boxer'
  color: 'brown' | 'white' | 'black'
}

type Animal = Cat | Dog

type cases = [
  Expect<Equal<LookUp<Animal, 'dog'>, Dog>>,
  Expect<Equal<LookUp<Animal, 'cat'>, Cat>>,
]

9 - Deep Readonly

type DeepReadonly<T> = {
  readonly [k in keyof T]: T[k] extends Record<any, any>
    ? T[k] extends Function
      ? T[k]
      : DeepReadonly<T[k]>
    : T[k]
}

10 - Tuple to Union

✍️ Answers

#10 - Tuples are JUST Arrays

For example:
#12 - my one-line solution

type TupleToUnion<T> = T extends any[] ? T[number] : never;

17 - Currying 1

type Curried<T extends (...args: any) => any> = {
  0: T extends (...args: [infer A]) => infer R ? (arg: A) => R : never,
  1: T extends (...args: [infer A, ...infer Args]) => infer R ? (arg: A) => Curried<(...args: Args) => R> : never,
}[T extends (...args: [any]) => any ? 0 : 1]

declare function Currying<T extends (...args: any) => any>(fn: T): Curried<T>

新题目 Test

请按照以下的模版填充相应的内容,一个 PR 会自动生成并保持与本 Issue 的内容同步。

你不需要提供详细的答案或教学,但请保证题目可解。

基本信息

# 题目难度
difficulty: easy # medium / hard / extreme

# 题目标题
title: 测试题3

# 题目标签
#tags: union, array # separate by comma

题目

在这里描述你的题目并给出一些例子。支持使用 Markdown。真的吗!

题目模版

以下是给予挑战者开始做题的代码模版,在大部分情况下你只需要修改类型名称使其符合你的题目与判题测试,实现的部分保持 any 即可。

type YourType = any

判题测试

请为你的题目提供一些判题测试,你可以使用 @type-challenges/utils 中提供的一些工具进行判断。

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

type cases = [
  Expect<Equal<true, true>>
]

4 - Pick

✍️ Answers

Name your title starting with the question no you are trying to answer.

For example:
#12 - my one-line solution

type MyPick<T, K extends keyof T> = { [S in K]: T[S] }

5 - Get Readonly Keys

type GetReadonlyKeys<T> = Exclude<{
  [K in keyof T]: Equal<{ [k in K]: T[K] }, { -readonly [k in K]: T[K] }> extends true ? never : K
}[keyof T], undefined>;

Union to Intersection

Info

difficulty: hard
title: Union to Intersection
tags: utils, infer

Question

Implement the advanced util type UnionToIntersection<U>

For example

type I = Union2Intersection<'foo' | 42 | true> // expected to be 'foo' & 42 & true

Template

type UnionToIntersection<U> = any

Test Cases

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

type cases = [
    Expect<Equal<UnionToIntersection<'foo' | 42 | true>, 'foo' & 42 & true>>,
    Expect<Equal<UnionToIntersection<(() => 'foo') | ((i: 42) => true)>, (() => 'foo') & ((i: 42) => true)>>,
]

18 - Length of Tuple

✍️ Answers

Name your title starting with the question no you are trying to answer.

For example:
12 - my one-line solution

type Length<T extends {readonly [x: number]: any; readonly length: number;}> = T['length'] 

12 - Chainable Options

✍️ Answers

Name your title starting with the question no you are trying to answer.

For example:
#12 - my one-line solution

type Chainable<Options = {}> = {
  option<K extends string, V>(key: K, value: V): Chainable<Options & { [S in K]: V }>
  get(): Options
}

This challenge is inspired by @types/yargs

Get Optional

Info

difficulty: hard
title: Get Optional
tags: utils, infer

Question

Implement the advanced util type GetOptional<T>, which remains all the optional fields

For example

type I = GetOptional<{ foo: number, bar?: string }> // expected to be { bar?: string }

Template

type GetOptional<T> = any

Test Cases

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

type cases = [
    Expect<Equal<GetOptional<{ foo: number, bar?: string }>, { bar?: string }>>,
    Expect<Equal<GetOptional<{ foo: undefined, bar?: undefined }>, { bar?: undefined }>>,
]

3 - Omit<T, K>

✍️ Answers

Name your title starting with the question no you are trying to answer.

For example:
#12 - my one-line solution

To get into this, you need to understand the Pick(#3) challenge first. The difference between it is that MyExclude is introduced. You can use the built-in Exclude to achieve that, however, a self-implemented one is included in the solution.

// TODO: explain what happened in MyExclude

type MyExclude<A, B> = A extends B ? never : A;

type MyOmit<T, K extends keyof T> = { [S in MyExclude<keyof T, K>]: T[S] }

12 - Chainable Options

✍️ Answers

#12 - Chainable Options

type Chainable<O = {}> = {
  option<K extends string, V>(key: K, value: V): Chainable<O & { [k in K]: V }>
  get(): O
}

17 - Currying 1

✍️ Answers

Name your title starting with the question no you are trying to answer.

For example:
12 - my one-line solution

type Unshift<T> = T extends [infer K, ...infer U] ? U : unknown
type Head<T> = T extends [infer K, ...infer U] ? K : unknown

type Curried<T, R> = T extends Array<any>
  ? T['length'] extends 1
    ? (args: Head<T>) => R
    : (args: Head<T>) => Curried<Unshift<T>, R>
  : never

declare function Currying<T extends unknown[], R>(fn: (...args: T) => R): Curried<T, R>

43 - Exclude

type MyExclude<T, U> =  T extends U ? never : T;

16 - Pop

works on TS3.9

type Unshift<T extends any[], K> =
    ((a: K, ...args: T) => void) extends ((...args: infer U) => void)
    ? U : never;

type Reverse<T extends any[], Target extends any[] = []> = {
    0: Target;
    1: (
        ((...args: T) => void) extends ((a: infer First, ...args: infer Rest) => void)
        ? Reverse<Rest, Unshift<Target, First>> : never
    );
}[T extends [any, ...any[]] ? 1 : 0];

type Pop<T extends any[]> =
    ((...args: Reverse<T>) => void) extends ((a: any, ...args: infer K) => void)
    ? Reverse<K> : never;

10 - Tuple to Union

✍️ Answers

Name your title starting with the question no you are trying to answer.

For example:
#12 - my one-line solution

export type TupleToUnion<T> = T extends Array<infer ITEMS> ? ITEMS : never

Promise.all

Info

difficulty: medium # medium / hard / extreme
title: Promise.all
tags: array, built-in 

Question

Type the function PromiseAll that accepts an array of PromiseLike objects, the returning value should be Promise<T> where T is the resolved result array.

const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise<string>((resolve, reject) => {
  setTimeout(resolve, 100, 'foo');
});

// expected to be `Promise<[number, number, string]>`
const p = Promise.all([promise1, promise2, promise3] as const)

Template

declare function PromiseAll(promises: any[]): any

Test Cases

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

const promise1 = Promise.resolve(3);
const promise2 = 42;
const promise3 = new Promise<string>((resolve, reject) => {
  setTimeout(resolve, 100, 'foo');
});

type cases = [
  Expect<Equal<PromiseAll([promise1, promise2, promise3] as const), Promise<[3, 42, string]>>>
]

Array/Tuple to Union

💡 Question Request

Feel free to raise a question that you have faced in your projects,
please clearly describe it so people can better help you with it.

If we found it's solvable and good to be in our collection,
we will properly credit you as the original question provider.

An ArrayToUnions<T> generic coverting array/tuple to its values' union

const arr = ['foo', 'bar'] as const

type union = ArrayToUnion<typeof arr> // expect to be 'foo' | 'bar'

3 - Omit<T, K>

type Diff<T extends string | number | symbol, U extends string | number | symbol> =
    ({[P in T]: P } & {[P in U]: never } & { [x: string]: never })[T];  
type MyOmit<T, K extends keyof T> = Pick<T, Diff<keyof T, K>>;

5 - Get Readonly Keys

✍️ Answers

5 - my solution

type ReadonlyKeys<T, R extends { [K in keyof T]: any } = Readonly<T>> = {
    [K in keyof T]: Equal<Pick<T, K>, Pick<R, K>> extends true ? K : never
}[keyof T]

11 - Tuple to Object

type TupleToObject<T extends ReadonlyArray<string | number>> = {
  [k in T[number]]: k
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.