TypeScript$Type-Define-TypeAliasAndInterface

84 阅读2分钟

TypeScript$Type-Define-TypeAliasAndInterface

1. Type Alias

就像值可以通过字面量 literal 来表示,也可以声明一个变量 variable 来接收。类型也可以通过字面量 literal 来表示,或者通过 type alias 来接收。Type alias 像是 const,不可以重新赋值。

type alias: a name for any type.

type Point = {
  x: number; // ; | , | new line
  y: number;
};
 
function printCoord(pt: Point) {
  console.log("The coordinate's x value is " + pt.x);
  console.log("The coordinate's y value is " + pt.y);
}
 
printCoord({ x: 100, y: 100 });
type ID = number | string;

1.1 Inheritance in type aliases - Intersection & type

使用 & 来表示 extends。(因为最终的结果是两方面都得满足)

// Extending a type via intersections
type Animal = {
  name: string;
}

type Bear = Animal & { 
  honey: boolean;
}

const bear = getBear();
bear.name;
bear.honey;

1.2 Recursion Types

Recursive types, are self-referential, and are often used to describe infinitely nestable types.

type NestedNumbers = number | NestedNumbers[]
 
const val: NestedNumbers = [3, 4, [5, 6, [7], 59], 221]
 
if (typeof val !== "number") {
  val.push(41)
  val.push("this will not work")
// error, Argument of type 'string' is not assignable to parameter of type 'NestedNumbers'.
}

1.3 type JSON

type JSONPrimitive = string | number | boolean | null
type JSONObject = { [k: string]: JSONValue }
type JSONArray = JSONValue[]
type JSONValue = JSONArray | JSONObject | JSONPrimitive
 
////// DO NOT EDIT ANY CODE BELOW THIS LINE //////
function isJSON(arg: JSONValue) {}
 
// POSITIVE test cases (must pass)
isJSON("hello")
isJSON([4, 8, 15, 16, 23, 42])
isJSON({ greeting: "hello" })
isJSON(false)
isJSON(true)
isJSON(null)
isJSON({ a: { b: [2, 3, "foo"] } })
 
// NEGATIVE test cases (must fail)
// @ts-expect-error
isJSON(() => "")
// @ts-expect-error
isJSON(class {})
// @ts-expect-error
isJSON(undefined)
// @ts-expect-error
isJSON(BigInt(143))
// @ts-expect-error
isJSON(isJSON)

2. Interfaces

interface 用来表示对象类型。既然有了 type alias,为什么还需要 interface 呢?因为 type alias 是个类似 const 的别名——不能重复,不能扩展。而 interface 和 type alias 最大的不同是 interface 是可以扩展的——多次声明同一个 interface 时,会合并为一个。(当然更明显的区别是 interface 只能用来声明对象类型)

interface declaration:  another way to name an object type.

interface Point {
  x: number;
  y: number;
}
 
function printCoord(pt: Point) {
  console.log("The coordinate's x value is " + pt.x);
  console.log("The coordinate's y value is " + pt.y);
}
 
printCoord({ x: 100, y: 100 });

2.1 Inheritance in interfaces: extends and implements

implements 也可以实现 type,要求是对象。

// Extending an interface
interface Animal {
  name: string;
}

interface Bear extends Animal {
  honey: boolean;
}

const bear = getBear();
bear.name;
bear.honey;
class LivingOrganism {
  isAlive() {
    return true
  }
}
interface AnimalLike {
  eat(food): void
}
interface CanBark {
  bark(): string
}
 
class Dog2
  extends LivingOrganism
  implements AnimalLike, CanBark
{
  bark() {
    return "woof"
  }
  eat(food) {
    consumeFood(food)
  }
}

- Differences Between Type Aliases and Interfaces

If you would like a heuristic, use interface until you need to use features from type.

官网中还列出了 type aliases 和 interface 其他的不同: