TypeScript interface接口

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'
}

 



總結:
1、interface 和 type 相類似,但不完全一致
2、interface 裏面有這些方式
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{}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章