問題: 對於一個接口,如何定義某個屬性為number,其它不確定的屬性都為string。
在解決這個問題時,never 類型就可以派上大用場。
看到這里,可能你二話不說,上來就要這些寫:
interface IType {
age: number;
[key: string]: string;
}
上面這樣寫是會報錯的。
這里要用到如下幾個知識點:
-
never
是任何類型的子類型,也就是說never
可以賦值給任何類型。下面的兩行代碼都不會有 TS 錯誤。
const a: number = '' as never;
const b: object = '' as never;
-
類型擴張
注:有些地方叫類型縮減,但是從表現出來的現象來看,叫類型縮減更合適一些。
兩個類型的聯合類型有可能會發生類型擴張,例如
type URStr = '123' | string; // 類型是 string
‘123'
是 string
類型的子類型,在經過聯合之后,聯合類型就變成 string
類型了。由於 '123'
類型范圍小,string
類型的范圍比較大,因此感覺叫類型擴張更合適一些。
有了上面兩個知識點,我們就可以寫成下面的樣子,在 ITypeKeyAny
類型中的 age
類型設置為 never
后,不會和下面的 string
類型沖突,因為 never
類型是任何類型的子類型。在和 ITypeAge
類型聯合時也不會沖突,並且 age
類型擴張為 number
類型。
interface ITypeAge {
age: number;
}
interface ITypeKeyAny {
age: never;
[key: string]: string;
}
type Itype = ITypeAge | ITypeKeyAny;
如有問題,歡迎指正~