TypeScript中interface和type的區別
原文:https://github.com/SunshowerC/blog/issues/7
interface VS type
TypeScript中定義類型的兩種方式
- 接口(interface)
- 類型別名(type alias)
interface只能定義對象類型
type聲明的方式可以定義組合類型、交叉類型和原始類型
相同點
1. 都可以描述一個對象或者函數
interface
interface User { name: string; age: number; } interface SetUser { (name: string, age: number): void; }
type
type User = { name: string; age: number } type SetUser = (name: string, age: number): void;
2. 都允許拓展(extends)
interface和type都可以拓展,並且兩者並不是互相獨立的,也就是說interface可以extends type, type也可以extends interface. 雖然效果差不多,但是語法不同。
interface extends interface
interface Name {
name: string;
}
interface User extends Name {
age: number;
}
type extends type
type Name = { name: string; } type User = Name & { age: number }
interface extends type
type Name = { name: string; } interface User extends Name { age: number; }
type extends interface
interface Name { name: string; } type User = Name & { age: number; }
不同點
1. type可以聲明基本類型別名、聯合類型、元祖等類型
// 基本類型別名
type Name = string; // 聯合類型
interface Dog { wong() } interface Cat { miao(); } type Pet = Dog | Cat; // 具體定義數組每個位置的類型
type PetList = [Dog, Pet];
2. type語句中還可以使用typeof獲取實例的類型進行賦值
// 當你想要獲取一個變量的類型時,使用typeof
let div = document.createElement('div'); type B = typeof div;
3. type其他騷操作
type StringOrNumber = string | number; type Text = string | { text: string }; type NameLookup = Dictionary<string, Person>; type Callback<T> = (data: T) => void; type Pair<T> = [T, T]; type Coordinates = Pair<number>; type Tree<T> = T | { left: Tree<T>, right: Tree<T> };
4. interface能夠聲明合並
interface User {
name: string;
age: number;
}
interface User {
sex: string;
}
User接口為:
{
name: string;
age: number;
sex: string;
}
總結
一般來說,能用interface實現,就用interface,如果不能就用type
Type Aliases的官方文檔:https://www.typescriptlang.org/docs/handbook/advanced-types.html#type-aliases
Type aliases create a new name for a type. Type aliases are sometimes similar to interfaces, but can name primitives, unions, tuples, and any other types that you’d otherwise have to write by hand.
(類型別名為類型創建一個新名稱。類型別名有時類似於接口,但可以命名原語、聯合、元組和其他任何類型,否則您必須手動編寫這些類型)
type Second = number; let timeInSecond: number = 10; let time: Second = 10;
Aliasing doesn’t actually create a new type - it creates a new name to refer to that type. Aliasing a primitive is not terribly useful, though it can be used as a form of documentation.
(別名實際上並不會創建一個新類型——它只是創建一個新名稱來引用該類型。盡管可以將原語用作一種文檔形式,但給原語起一個別名並不是非常有用)
Just like interfaces, type aliases can also be generic - we can just add type parameters and use them on the right side of the alias declaration:
(就像接口一樣,類型別名也可以是泛型的-我們可以添加類型參數並在別名聲明的右側使用它們)
type Container<T> = { value: T };
We can also have a type alias refer to itself in a property:
(我們也可以有一個類型別名引用自己的屬性)
type Tree<T> = { value: T; left?: Tree<T>; right?: Tree<T> };
腦殼兒疼~~