# TS 练习题
1-30 题目来源:https://juejin.cn/post/7009046640308781063 (opens new window)
记录一下优秀的题目,同时也写下自己的代码与理解
# 第一题:extends
type User = {
id: number
kind: string
}
function makeCustomer<T extends User>(u: T): T {
return {
id: u.id,
kind: "customer"
}
}
// Error(TS Playground:v4.6.2)
// Type '{ id: number; kind: string; }' is not assignable to type 'T'.
// '{ id: number; kind: string; }' is assignable to the constraint of type 'T', but 'T' could be instantiated with a different subtype of constraint 'User'.
我的代码:
function makeCustomer<T extends User>(u: T): T {
return {
...u,
id: u.id,
kind: "customer"
}
}
// 此处需要注意extends的用法:
// https://www.typescriptlang.org/docs/handbook/2/conditional-types.html#inferring-within-conditional-types
// https://cloud.tencent.com/developer/article/1884330
# 第二题:类型保护
function f(a: string | number, b: string | number) {
if (typeof a === "string") {
return a + ":" + b // no error but b can be number!
} else {
return a + b // error as b can be number | string
}
}
f(2, 3) // Ok
f(1, "a") // Error
f("a", 2) // Error
f("a", "b") // Ok
我的代码:
function f(a: string | number, b: string | number) {
if (typeof a === "string" || typeof b === "string") {
return a + ":" + b // no error but b can be number!
} else {
return a + b // error as b can be number | string
}
}
# 第三题:Partial
type Foo = {
a: number
b?: string
c: boolean
}
// 测试用例
type SomeOptional = SetOptional<Foo, "a" | "b">
// type SomeOptional = {
// a?: number; // 该属性已变成可选的
// b?: string; // 保持不变
// c: boolean;
// }
我的代码:
// Required 是变为必选,非此题要求。
type SetOptional<T, P extends keyof T> = Simplify<
Partial<Pick<T, P>> & Required<Pick<T, keyof Omit<T, P>>>
>
type Simplify<T> = {
[K in keyof T]: T[K]
}
# 第四题:Pick
interface Example {
a: string
b: string | number
c: () => void
d: {}
}
// 测试用例:
type StringKeysOnly = ConditionalPick<Example, string>
//=> {a: string}
我的代码:
type ConditionalPick<T, P> = {
[K in keyof T as T[K] extends P ? K : never]: T[K]
}
# 第五题
type Fn = (a: number, b: string) => number
type AppendArgument<F, A> = // 你的实现代码
type FinalFn = AppendArgument<Fn, boolean>
// (x: boolean, a: number, b: string) => number
我的代码:
d