交叉類型(Intersection Types)(交集)
type A = string & number
很顯然 A 的結果是 never侮腹,因為字符串和數(shù)字是兩種完全不同的東西,所以一般交叉類型父阻,我們不會用在普通類上
type 有左手的人 = {
left: string;
}
type 有右手的人 = {
right: string;
}
type C = 有左手的人 | 有右手的人
type D = 有左手的人 & 有右手的人
以上的 C、D 類型用一張圖表示:
思考"有左手的人" 可以有"右手"嗎履婉?
type 有左手的人 = {
left: string;
}
const a: 有左手的人 = {
left: '左手',
right: '右手', // TODO: 這里會有報錯
}
很顯然荒椭,這里的代碼報錯了,但是從邏輯上來講狸棍,"有左手的人" 難道不能有"右手"嗎?草戈,再來看接下來的栗子:
type 有左手的人 = {
left: string;
}
const b = {
left: '左手',
right: '右手',
}
const a: 有左手的人 = b
神奇的是唐片,竟然不報錯了,這就是 ts 很奇怪的地方费韭,初始化的時候不能有多余的東西
接口也能交集
interface 有左手的人 {
left: string;
}
interface 有右手的人 {
right: string;
}
type 完整的手 = 有左手的人 & 有右手的人
特殊情況
普通對象
type Person = {
name: string;
age: number;
id: string;
}
type User = Person & {
id : number; // TODO: 注意:這里并沒有報錯
email: string;
}
const a: User = {
id: 1, // TODO: 這里報錯了,并且提示類型為 never抢埋,
name: 'Jack',
email: 'qq.com',
}
但是稍微改造一點督暂,還有更特殊的情況
type Person = {
name: string;
age: number;
id: 'A'; // TODO: 這里更具體了
}
type User = Person & {
id : 'B'; // TODO: 這里更具體了
email: string;
}
const a: User = { // TODO: 這里直接提示 User 類型為 never,
id: 1,
name: 'Jack',
email: 'qq.com',
}
這就很難解釋了饥努,直接記住這種情況把~
函數(shù)
type A = {
method: (n: number) => void
}
type B = {
method: (n: string) => void
}
const b: B = {
method: n => { // TODO: 沒有報錯
console.log(n)
}
}
可以發(fā)現(xiàn)當為函數(shù)的時候這里沒有報錯八回,且參數(shù) n 的類型為 string | number,
一個接受參數(shù)類型為 number 的方法辽社,一個接受參數(shù)類型為 string 的方法,這兩個方法有沒有交集呢戳葵?到目前來看已經(jīng)很難想清楚了汉匙,明明是交集,怎么會得出并集噩翠!我們再來驗證一下:
type F1 = (n: number) => void
type F2 = (n: string) => void
type X = F1 & F2
const x: X = (n) => {
console.log(n)
}
也沒有報錯,且參數(shù) n 的類型為 string | number
也就是說擅笔,如果我們再在做兩個對象交集的時候,遇到 key 的名字沖突的時候猛们,那么他會對這個屬性進行交集,且遞歸的交弯淘。
但是特殊在函數(shù)這里,函數(shù)的交集假勿,會得到參數(shù)的并集态鳖,說實話我又不是很理解了,沒辦法按實踐的結果來死記硬背把~