题目描述
获取两个接口类型中的差值属性。
type Foo = {
a: string;
b: number;
}
type Bar = {
a: string;
c: boolean
}
type Result1 = Diff<Foo,Bar> // { b: number, c: boolean }
type Result2 = Diff<Bar,Foo> // { b: number, c: boolean }
题解
// ============= Test Cases =============
import type { Equal, Expect } from './test-utils'
type Foo = {
name: string
age: string
}
type Bar = {
name: string
age: string
gender: number
}
type Coo = {
name: string
gender: number
}
type cases = [
Expect<Equal<Diff<Foo, Bar>, { gender: number }>>,
Expect<Equal<Diff<Bar, Foo>, { gender: number }>>,
Expect<Equal<Diff<Foo, Coo>, { age: string; gender: number }>>,
Expect<Equal<Diff<Coo, Foo>, { age: string; gender: number }>>,
]
// ============= Your Code Here =============
type Diff0<L, R> = Omit<L & R, keyof (L | R)>
type Diff1<L, R> = {
[P in keyof L | keyof R
as Exclude<P, keyof (L | R)>
]:
P extends keyof L
? L[P]
: P extends keyof R
? R[P]
: never
}
type Diff<L, R> = {
[P in keyof L | keyof R
as P extends L
? P extends R
? never
: P
: P
]:
P extends keyof L
? L[P]
: P extends keyof R
? R[P]
: never
}
题解1:使用Omit和联合类型
type Diff0<L, R> = Omit<L & R, keyof (L | R)>
-
联合类型
L | R:-
L | R是L和R的联合类型,表示一个类型可以是L或R -
keyof (L | R)会提取L和R中所有键的并集
-
-
交叉类型
L & R:L & R是L和R的交叉类型,表示一个类型同时具有L和R的所有属性
-
Omit类型:-
Omit<T, K>是一个内置类型工具,它会从类型T中排除键K -
Omit<L & R, keyof (L | R)>会从L & R中排除L和R的所有键的并集
-
题解2:使用条件类型和Exclude
type Diff1<L, R> = {
[P in keyof L | keyof R
as Exclude<P, keyof (L | R)>
]:
P extends keyof L
? L[P]
: P extends keyof R
? R[P]
: never
}
-
遍历联合类型:
[P in keyof L | keyof R]:遍历L和R的所有键的联合类型
-
条件映射:
-
as Exclude<P, keyof (L | R)>:排除L和R的所有键的并集
-
-
条件赋值:
-
P extends keyof L ? L[P] : P extends keyof R ? R[P] : never:-
如果
P是L的键,则返回L[P] -
如果
P是R的键,则返回R[P] -
否则,返回
never
-
-
题解3:使用条件类型和never
type Diff<L, R> = {
[P in keyof L | keyof R
as P extends L
? P extends R
? never
: P
: P
]:
P extends keyof L
? L[P]
: P extends keyof R
? R[P]
: never
}
-
遍历联合类型:
[P in keyof L | keyof R]:遍历L和R的所有键的联合类型
-
条件映射:
-
as P extends L ? P extends R ? never : P : P:-
如果
P是L的键,并且P也是R的键,则将P映射为never(即排除公共键) -
否则,保留
P
-
-
-
条件赋值:
-
P extends keyof L ? L[P] : P extends keyof R ? R[P] : never:-
如果
P是L的键,则返回L[P] -
如果
P是R的键,则返回R[P] -
否则,返回
never
-
-