Day15: 【TypeScript 学起来】Interface VS Type Aliases 用法与差别

上一篇讲到 interface,今天这篇会来讲 type, 他们两个功能几乎很像,但还是有些不一样,让我们看下去。不过这之前先介绍一下 Type Aliases(型别别名)。


Type Aliases(型别别名)

Type Aliases(型别别名) 用来给一个型别起个新名字,起手式就是使用type来进行宣告。他比较常用於联合型别,但他也可以跟 interface 一样可以定义物件、function, 下面也会介绍他们的差别。

A type alias is exactly that - a name for any type.

如以下例子,id 型别有点重复:

const printId = (id: string | number) => {
    console.log(`my id is ${id}`)
}

const sayHi = (person:{name: string, id: string | number}) => {
    console.log(`hi, ${person.name}! your id is ${id}.`)
}

这时候我们就可以使用Type Aliases(型别别名),给string | number定义型别,帮助我们简化程序码,让型别可以共用。是不是整齐很多,也方便後续维护。

type StringOrNum = string | number;
type objWithName = {name: string, id : StringOrNum };

const printId = (id: StringOrNum) => {
    console.log(`${name}'s id is ${id}`)
}

const sayHi = (person:objWithName) => {
     console.log(`hi, ${person.name}! your id is ${id}.`)
}

Type Aliases(型别别名) vs Interfaces(介面)

前面也有提到他们功能很像, 我们来看看他们的相同处及不同处有哪些:

相同处1: 都可以定义物件(object, function, array)形状

都可使用 readonly / 可选属性 / 新增任意属性 / function overload

interface:

//object
interface IUser {
    readonly id: number; 
    name: string;
    age?: number;
    [propName: string]: any;
    getWeight(): number;
    getWeight(x?: number): number;
}

//function
interface SetPoint {
  (x: number, y: number): void;
}

//array
interface NumberArray {
    [index: number]: number;
}

type:

//object
type User = {
    readonly id: number; 
    name: string;
    age?: number;
    [propName: string]: any;
    getWeight(): number;
    getWeight(x?: number): number;
}

//function
type SetPoint = (x: number, y: number) => void;

//array
type NumberArray = {
    [index: number]: number;
}

相同处2: 都可以 extend , 只是用法不同

Extending an interface:

interface Animal {
  name: string
}

interface Bear extends Animal {
  honey: boolean
}

Extending a type via intersections:

type Animal = {
  name: string
}

type Bear = Animal & { 
  honey: boolean 
}

interface extends type:

type Name = { 
  name: string; 
}
interface User extends Name { 
  age: number; 
}

Extending interface & type via intersections:

interface Name { 
  name: string; 
}
type User = Name & { 
  age: number; 
}

相同处3: 都可以被 class implement

interface:

interface Point {
  x: number;
  y: number;
}

class SomePoint implements Point {
  x = 1;
  y = 2;
}

type:

type Point2 = {
  x: number;
  y: number;
};

class SomePoint2 implements Point2 {
  x = 1;
  y = 2;
}

但要特别注意, 如果是 union type 是无法被 implements 的。

type PartialPoint = { x: number; } | { y: number; };

//error: A class can only implement an object type or intersection of object types with statically known members.
class SomePartialPoint implements PartialPoint {
  x = 1;
  y = 2;
}

不同处1: interface 名称可以重复定义并合并 , type 不行

interface:

interface Window {
  title: string
}

interface Window {
  ts: TypeScriptAPI
}

type:

type Window = {
  title: string
}

type Window = {
  ts: TypeScriptAPI
}// Error: Duplicate identifier 'Window'.


不同处2: type 可以描述 primitive type、tuple、union type 等, interface 无法

//primitive type 
type Name = string

interface Dog {
    arfarf();
}
interface Cat {
    meow();
}

//union type
type Pet = Dog | Cat

//tuple
type PetList = [Dog, Pet]

感想阅读~明天会来讲 index signature,明天见!

参考资料

https://willh.gitbook.io/typescript-tutorial/advanced/type-aliases
https://www.typescriptlang.org/docs/handbook/2/everyday-types.html#type-aliases
https://ithelp.ithome.com.tw/articles/10216626
https://ithelp.ithome.com.tw/articles/10224646
https://github.com/SunshowerC/blog/issues/7#type-extends-type


<<:  Day15 资料库-model的创建(1)

>>:  [Day 17] Facial Recognition - siamese networks: 只是一个开始

day 8 - 程序码也要断舍离

生活要断舍离, 程序码也要喔。 写Go只要一支main.go就可以开始写了, 想写多长就写多长, 要...

我们的基因体时代-AI, Data和生物资讯 Day09-合成生物学与机器学习

上一篇我们的基因体时代-AI, Data和生物资讯 Day08-合成生物学与机器学习分享合成生物学领...

如何取出物件中重复/不重复的值

在上一篇中写了关於阵列的做法 假如今天我们将阵列改成物件,该怎麽去实现它呢? 先给一个全域值: co...

DAY10 - 如何挑选自学的教材

前言 今天是铁人赛的第十天,要来开始说说大叔的前端之路 并且说明我都看那些教学文件或影片 我是去年中...

【从零开始的Swift开发心路历程-Day1】工欲善其事,必先利其器

如果你想成为一名Swift开发人员,光是只有一台MacBook是不够的~还必须要有一个好的开发环境,...