const getPersonName = person => { console.log(person.name); } const setPersonName = (person, name) => { person.name = name; } /** * 這是沒用 ts 語法,這樣會有問題,比如 person 是 undefined * 那麼整個語句就會報錯了 * 所以爲了避免錯誤,person 一定要有 name 這個屬性的話,該怎麼做 * 給 person 加一個類型註解 */ const getPersonName1 = (person: {name: string}) => { console.log(person.name); } const setPersonName1 = (person: {name: string}, name: string) => { person.name = name; } /** * 這個時候,person 都是一樣的類型,裏面都包含 name, * 這個參數在 getPersonName1 寫了一遍,又在 setPersonName1 寫了一遍 * 其實這個寫一次就成了,就可以用 interface */ interface Person{ name: string } const getPersonName2 = (person: Person) => { console.log(person.name); } const setPersonName2 = (person: Person, name: string) => { person.name = name; } /** * 所以通用型的集合可以用 interface 表示出來 * 之前還用過 type */ type Person1 = { name: string } const getPersonName3 = (person: Person1) => { console.log(person.name); } const setPersonName3 = (person: Person1, name: string) => { person.name = name; } /** * 這樣寫好像也沒有問題,那麼 interface 和 type 有什麼區別呢? * 區別不大,但是還是有區別的 * * 比如 type Person1 = string * type 中的變量可以直接代表基礎類型,interface 不行,它只能代表個對象或者函數 * 所以類型別名和接口還是有區別的。但是通用型的規範是用接口表示,實在不行才用類型別名 */ interface Person2 { // readonly name: string, // 表示這個屬性只讀,不允許後續有修改 name 的操作 name: string, age?: number // 表示這個屬性可有可毋 } const getPersonName4 = (person: Person2): void => { console.log(person.name); } const setPersonName4 = (person: Person2, name: string) => { person.name = name; } const person = { name: 'zina', sex: 'girl' // 這裏允許傳遞其他屬性,interface 裏面是必須有的屬性 } getPersonName4(person); getPersonName4({ name: 'zina', sex: 'girl' }) /** * 當以字面量的形式傳遞會報錯,而以 person 變量的形式不會報錯 * 當以字面量傳遞的時候,這個時候 ts 會對這種方式進行強校驗 * 也就是這裏面只能有name,age是選填的,如果不一樣就會提示錯誤 * 當把這個變量緩存一下,就不會強校驗,只要有 interface 裏面的東西 * 再多出點東西也沒有關係 * * 如果說我確實是需要傳遞其他參數,而且就想用字面量的形式,這個時候可以給接口加上限制 */ interface Person2 { name: string, age?: number // 表示這個屬性可有可無 [propName: string]: any } getPersonName4({ name: 'zina', sex: 'girl' }) // 這個時候就不會報錯了 interface Person3 { name: string, age?: number // 表示這個屬性可有可無 [propName: string]: any, // 允許傳遞其他屬性 say(): string // 要求這裏面有個 say 方法,返回值一定要是 string 類型 } // 這時候類去應用這個接口,就必須有 name 和 say, 不然會報錯 class User implements Person3{ name = 'zina' say() { return 'hi' } } // 接口可以互相繼承 interface Teacher extends Person3{ teach(): string } // 接口以函數的方式定義 interface SayHi { (word: string): string } // 這個函數必須接收一個 string 類型的參數,同時返回值也是 string 類型 const say:SayHi = () => { return 'hi' }
interface Person3 { name: string, readonly shortName: string, // 表示這個屬性只讀,不允許後續有修改 name 的操作 age?: number // 表示這個屬性可有可無 [propName: string]: any, // 允許傳遞其他屬性 say(): string // 要求這裏面有個 say 方法,返回值一定要是 string 類型 }
3、接口可以繼承
interface Teacher extends Person3{
teach(): string
}
4、接口除了以對象形式定義,還能以函數形式定義
interface SayHi { (word: string): string } // 這個函數必須接收一個 string 類型的參數,同時返回值也是 string 類型 const say:SayHi = () => { return 'hi' }
5、一個類應用接口,語法是 implements
class User implements Person3{}