type-challenges / type-challenges Goto Github PK
View Code? Open in Web Editor NEWCollection of TypeScript type challenges with online judge
Home Page: https://tsch.js.org/
License: MIT License
Collection of TypeScript type challenges with online judge
Home Page: https://tsch.js.org/
License: MIT License
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
The challenges get updated with stricter rules in #173, check out #172 for a more proper answer.
type First<T extends any[]> = T extends [infer H, ...infer _] ? H : never
Name your title starting with the question no you are trying to answer.
For example:
#12 - my one-line solution
type MyReturnType<T extends Function> =
T extends (...args: any) => infer R
? R
: never
Extend readings:
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
type MyPick<T, K> = {
[k in keyof T & K]: T[k]
}
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
type MyOmit<T, K> = {
[k in Exclude<keyof T, K>]: T[k]
}
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] }
difficulty: easy
title: Exclude
#tags: built-in
Implement the built-in Exclude<T, U>
Exclude from T those types that are assignable to U
type MyExclude<T, U> = any
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>>>,
]
type Last<T extends any[]> = T extends [...infer _, infer L] ? L : never
type MyPick<T, K extends keyof T> = {
[k in K]: T[k]
}
type Pop<T extends any[]> = T extends [...infer I, infer _] ? I : never
difficulty: hard
title: Get Required
tags: utils, infer
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 }
type GetRequired<T> = any
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 }>>,
]
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]
type First<T extends any[]> = T extends [infer F, ...any[]] ? F : never;
type MyPick<T, K extends keyof T> = { [S in K]: T[S] }
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] }
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] }
}
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 TupleToUnion<T> = T[number & keyof T]
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.
Basic info of your challenge questions,
difficulty: medium # medium / hard / extreme
title: Type Lookup
tags: union, map
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`
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
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>>,
]
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]
}
type TupleToUnion<T> = T extends any[] ? T[number] : never;
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>
请按照以下的模版填充相应的内容,一个 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>>
]
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] }
type MyReturnType<T> = T extends (...args: any) => infer R ? R : never
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>;
difficulty: hard
title: Union to Intersection
tags: utils, infer
Implement the advanced util type UnionToIntersection<U>
For example
type I = Union2Intersection<'foo' | 42 | true> // expected to be 'foo' & 42 & true
type UnionToIntersection<U> = any
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)>>,
]
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']
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
difficulty: hard
title: Get Optional
tags: utils, infer
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 }
type GetOptional<T> = any
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 }>>,
]
type TupleToObject<T extends readonly any[]> = { [K in T[number]]: K }
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] }
type Length<T extends ReadonlyArray<any>> = T['length']
type MyReadonly<T> = { readonly [K in keyof T]: T[K]}
#12 - Chainable Options
type Chainable<O = {}> = {
option<K extends string, V>(key: K, value: V): Chainable<O & { [k in K]: V }>
get(): O
}
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>
assetion
should be assertion
type MyExclude<T, U> = T extends U ? never : T;
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;
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
type MyReadonly<T> = {
readonly [k in keyof T]: T[k]
}
difficulty: medium # medium / hard / extreme
title: Promise.all
tags: array, built-in
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)
declare function PromiseAll(promises: any[]): any
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]>>>
]
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'
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 - 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]
type MyOmit<T, K> = Pick<T, Exclude<keyof T, K>>
type TupleToObject<T extends ReadonlyArray<string | number>> = {
[k in T[number]]: k
}
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.