溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

TypeScript中的接口和泛型是什么

發(fā)布時(shí)間:2022-03-16 13:33:47 來(lái)源:億速云 閱讀:148 作者:小新 欄目:開(kāi)發(fā)技術(shù)

這篇文章給大家分享的是有關(guān)TypeScript中的接口和泛型是什么的內(nèi)容。小編覺(jué)得挺實(shí)用的,因此分享給大家做個(gè)參考,一起跟隨小編過(guò)來(lái)看看吧。

接口

使用 interface 關(guān)鍵字來(lái)定義數(shù)據(jù)類(lèi)型

對(duì)象類(lèi)型

當(dāng)存在于較長(zhǎng)的數(shù)據(jù)類(lèi)型約束時(shí),我們可以通過(guò) type 關(guān)鍵字 為類(lèi)型注解起別名,也可以通過(guò)接口來(lái)定義

type UserType = { name: string; age?: number };
const user: UserType = {
  name: "kiki",
  age: 18,
};
interface IUserType { name: string; age?: number }
const person: IUserType = {
  name: 'alice',
  age: 20
}

索引類(lèi)型

interface 和type定義對(duì)象都可以為只知道key的類(lèi)型,不知道具體 key 值的時(shí)候,進(jìn)行類(lèi)型的定義

interface ILanguage {
  [index: number]: string;
}
const language: ILanguage = {
  0: "html",
  1: "css",
  2: "js",
};
type Score = {
  [name: string]: number;
}
const score: Score = {
  Chinese: 120,
  math: 95,
  Englist: 88,
};

函數(shù)類(lèi)型

定義函數(shù)時(shí),interface 和 type 的語(yǔ)法稍有不同

interface ISelfType {
  (arg: string): string;
}
type LogType = (arg: string) => string;
function print(arg: string, fn: ISelfType, logFn: LogType) {
  fn(arg);
  logFn(arg);
}
function self(arg: string) {
  return arg;
}
console.log(print("hello", self, self));

繼承

接口可以實(shí)現(xiàn)多繼承,繼承后的接口具備所有父類(lèi)的類(lèi)型注解

interface ISwim {
  swimming: () => void;
}
interface IEat {
  eating: () => void;
}
interface IBird extends ISwim, IEat {}
const bird: IBird = {
  swimming() {},
  eating() {},
};

交叉類(lèi)型

交叉類(lèi)型其實(shí)是與的操作,用 & 符號(hào),將接口進(jìn)行與操作后,實(shí)質(zhì)上需要滿足所有與操作接口的類(lèi)型注解

interface ISwim {
  swimming: () => void;
}
interface IEat {
  eating: () => void;
}
type Fish = ISwim | IEat;
type Bird = ISwim & IEat;
const fish: Fish = {
  swimming() {},
};
const bird: Bird = {
  swimming() {},
  eating() {},
};
export {}

接口實(shí)現(xiàn)

接口可以通過(guò)類(lèi)使用 implements 關(guān)鍵字來(lái)實(shí)現(xiàn),類(lèi)只能繼承一個(gè)父類(lèi),但是可以實(shí)現(xiàn)多個(gè)接口

interface ISwim {
  swimming: () => void
}
interface IEat {
  eating: () => void
}
class Animal {}
class Fish extends Animal implements ISwim, IEat {
  swimming(){}
  eating(){}
}
class Person implements ISwim {
  swimming(){}
}
function swimAction(iswim: ISwim){
  iswim.swimming()
}
swimAction(new Fish())
swimAction(new Person())

沒(méi)有實(shí)現(xiàn)接口的類(lèi),自然是沒(méi)有該接口中的方法

TypeScript中的接口和泛型是什么

interface 和 type 的區(qū)別

很多時(shí)候 interface 和 type 是相同的,但有一個(gè)明顯區(qū)別在于 interface 可以重復(fù)定義,類(lèi)型注解會(huì)累加,而 type 重復(fù)定義會(huì)報(bào)錯(cuò)

TypeScript中的接口和泛型是什么

字面量賦值

直接把字面量賦值類(lèi)型給變量時(shí),會(huì)對(duì)字面量進(jìn)行類(lèi)型推導(dǎo),多出的屬性會(huì)報(bào)錯(cuò)

TypeScript中的接口和泛型是什么

但是將對(duì)象的引用賦值的話,會(huì)進(jìn)行 freshness 擦除操作,類(lèi)型檢測(cè)時(shí)將多余的屬性擦除,如果依然滿足類(lèi)型就可以賦值

TypeScript中的接口和泛型是什么

枚舉類(lèi)型

枚舉類(lèi)型通過(guò) enum 關(guān)鍵字來(lái)定義,它和聯(lián)合類(lèi)型實(shí)現(xiàn)的功能類(lèi)似,但是枚舉類(lèi)型的代碼閱讀性會(huì)更強(qiáng)一些

enum Direction {
  LEFT,
  RIGHT,
  TOP,
  BOTTOM,
}
function turnDirection(direction: Direction) {
  switch (direction) {
    case Direction.LEFT:
      break;
    case Direction.RIGHT:
      break;
    case Direction.TOP:
      break;
    case Direction.BOTTOM:
      break;
    default:
      const foo: never = direction;
      break;
  }
}
turnDirection(Direction.LEFT);

泛型

泛型函數(shù)

當(dāng)不確定入?yún)⒌念?lèi)型時(shí),可以定義類(lèi)型注解為泛型,使用的時(shí)候再指定具體類(lèi)型,使用 <> 來(lái)進(jìn)行泛型的定義。

function self<T>(element: T) {
  return element;
}
self<string>("alice");
self<number>(2);
self<null>(null);

如果沒(méi)有定義類(lèi)型,ts會(huì)進(jìn)行類(lèi)型推導(dǎo),有可能并不是我們希望的類(lèi)型,如以下字符串推導(dǎo)出來(lái)不是”string“字符串類(lèi)型,而是“hello”字面量類(lèi)型。

TypeScript中的接口和泛型是什么

當(dāng)存在多個(gè)參數(shù)時(shí),在泛型中定義多個(gè)即可

function foo<T, E, O>(a: T, b: E, c: O){}
foo(1, 'alice', false)
foo(['alice'], undefined, null)

泛型接口

在接口中使用泛型,將類(lèi)型注解寫(xiě)在接口名后

interface Person<T, E> {
  name: T;
  age: E;
}
const person: Person<string, number> = {
  name: "alice",
  age: 20,
};

在接口中使用泛型是無(wú)法進(jìn)行類(lèi)型推導(dǎo)的,使用的時(shí)候必須指定具體的類(lèi)型

TypeScript中的接口和泛型是什么

除非在接口定義的時(shí)候給泛型設(shè)置了默認(rèn)值

interface Book<T = string, E = number> {
  category: T;
  price: E;
}
const book: Book = {
  category: "nature",
  price: 88.6,
};
const dictionary: Book<number, string> = {
  category: 1,
  price: '88'
}

泛型類(lèi)

類(lèi)中定義的方式,只是將具體的數(shù)據(jù)類(lèi)型替換成了泛型,在類(lèi)中是可以進(jìn)行類(lèi)型推導(dǎo)的

class Point<T> {
  x: T;
  y: T;
  z: T;
  constructor(x: T, y: T, z: T) {
    this.x = x;
    this.y = y;
    this.z = z;
  }
}
new Point("1.55", "2.34", "3.67");
new Point(1.55, 2.34, 3.67);

類(lèi)型約束

泛型可以通過(guò)繼承來(lái)進(jìn)行類(lèi)型約束

只需要傳入的參數(shù)滿足泛型的條件,即有 length 屬性

interface ILength {
  length: number;
}
function getLength<T extends ILength>(element: T) {
  return element.length;
}
getLength("alice");
getLength(["alice", "kiki", "lucy"]);
getLength({ length: 5 });

接口、枚舉、泛型 這些類(lèi)型在JavaScript都是沒(méi)有的,但在TypeScirpt中都是非常重要的類(lèi)型注解。

感謝各位的閱讀!關(guān)于“TypeScript中的接口和泛型是什么”這篇文章就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,讓大家可以學(xué)到更多知識(shí),如果覺(jué)得文章不錯(cuò),可以把它分享出去讓更多的人看到吧!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI