Pick
Pick<Template,props1 | props2>,get a new type of object only contain specific properties
here is my answer
type MyPick<Target extends Object, SelectedProperties extends keyof Target> = {
[key in SelectedProperties]: Target[key]
}
interface Todo {
title: string
description: string
completed: boolean
}
type TodoPreview = MyPick<Todo, 'title' | 'completed'>
const todo: TodoPreview = {
title: 'Clean room',
completed: false,
}
Readonly & Partial
same as the test above,
interface Todo {
title: string
description: string
}
type MyReadonly<Target extends Object> = {
readonly [key in keyof Target]: Target[key]
}
type Mypartial<Target extends Object> = {
[key in keyof Target]? : Target[key]
}
const todo: MyReadonly<Todo> = {
title: "Hey",
description: "foobar"
}
todo.title = "Hello" // Error: cannot reassign a readonly property
todo.description = "barFoo" // Error: cannot reassign a readonly property
First of Array
maybe infer ?
type arr1 = ['a', 'b', 'c']
type arr2 = [3, 2, 1]
type First<Target> = Target extends [infer R, ...unknown[]] ? R : never
type head1 = First<arr1> // expected to be 'a'
type head2 = First<arr2> // expected to be 3
it seems I always get the complex answer rather than simpler one
the simpler ones
// simpler one
type First<T extends any[]> = T[0]
type First<T extends any[]> = T extends [] ? never : T[0]
type First<T extends any[]> = T['length'] extends 0 ? never : T[0]
type First<T> = T extends [infer P, ...infer Rest] ? P : never
Length
maybe just return the property ‘length’ ?
type tesla = ['tesla', 'model 3', 'model X', 'model Y']
type spaceX = ['FALCON 9', 'FALCON HEAVY', 'DRAGON', 'STARSHIP', 'HUMAN SPACEFLIGHT']
// my answer
type Length<T> = T extends { length: number } ? T['length'] : never
// the author`s answer
type Length<T extends any[]> = T['length']
type teslaLength = Length<tesla> // expected 4
type spaceXLength = Length<spaceX> // expected 5
so far so good.just get it on !
Exclude
I guess it is a not or ‘~’ .(A few minutes later ~ ) It failed 💔
I just tried to get all the keys of Target and minus the specific ones. But just don`t know how to do it
here is the answer
type Exclude<T, U> = T extends U ? never : T
just get the wrong question… maybe i am thinking about Omit
As the author said ,the union type in typescript do like this below .but still can not figure out why is it
Exclude<'a'|'b','a'|'b'>
// equals to
Exclude<'a','a'|'c'> | Exclude<'b','a'|'c'>
By now , I just know how to get my problem fixed
interface Todo {
title: string
description: string
completed: boolean
}
type HisExclude<T, U> = T extends U ? never : T
type MyExclude<T extends Object, props extends keyof T> = {
// this get wrong
// key in ((keyof T) extends props ? never : (keyof T))]: T[key]
// this get right
// should be no difference
[key in HisExclude<keyof T, props>]: T[key]
}
type TodoPreview = MyExclude<Todo, 'title' | 'completed'>
const todo: TodoPreview = {
description: "this"
}
Await
get type from Promise, looks like infer could help. Here is my answer
type Await<T> = T extends Promise<infer R> ? R : never
const value: Await<Promise<string>> = "string"
Promise may be recursive, so the author`s anwer is as below
type MyAwaited<T extends Promise<unknown>> = T extends Promise<infer P>
? P extends Promise<unknown> ? MyAwaited<P> : P
: never
If
sorry , I just see the anwer without having a deep though…
So just do it with extends. 😊
type A = If<true, 'a', 'b'> // expected to be 'a'
type B = If<false, 'a', 'b'> // expected to be 'b'
type If<Condition extends boolean, A, B> = Condition extends true ? A : B
Concat
looks a little difficult ? maybe ‘…’ ?
amazing! It works!
type Result = Concat<[1], [2]> // expected to be [1, 2]
type Concat<First extends unknown[], Second extends unknown[]> =
[...First, ...Second]
The author give a better answer which consider situation given element that is not array
type Concat<P, Q> = [ ...P extends any[] ? P : [P],
...Q extends any[] ? Q : [Q],
]
Include
maybe extends or & ?, The key is to get the element type of array
By searching the Internet, it reminded me that I can get the type by T[number]. Ok, no question now!
type isPillarMen = Includes<['Kars', 'Esidisi', 'Wamuu', 'Dio'], 'Dio'> // expected to be `false`
type Includes<T extends unknown[], P> = P extends T[number] ? true : false
The author propose another question
type isPillarMen = Includes<[boolean], false>
// true, but should be a false
true and false are both extends from boolean, that is the reason
So a exact equal should help
the rest of Include is coming soon ,I haven`t figure it out …
Push
things get easier now, just use ‘…’ like concat
type Result = Push<[1, 2], '3'> // [1, 2, '3']
type Push<T extends unknown[], K> = [...T, K]
Unshift
same as Push
type Result = Unshift<[1, 2], 0> // [0, 1, 2,]
type Unshift<T extends unknown[], K> = [K,...T]
Parameters
I think the answer is infer (True)
type MyParameters<T> = T extends (...args: infer R) => unknown ? R : never
type paras=MyParameters<(str: string, num: number) => boolean>
That is the end!
For me ,I can handle a few by myself, some by searching the internet, only two or three question I can`t fix up. The question Include is the most changeling for me. By now ,I haven`t figure out why 😒
Learnt the extends in typescript is an assignment, which makes it hard to understand