Skip to content
Published at:

Object Types

ts
// 匿名 Object
function greet(person: { name: string; age: number }) {
  return 'Hello ' + person.name;
}

// 用 interface
interface Person {
  name: string;
  age: number;
}

function greet(person: Person) {
  return 'Hello ' + person.name;
}

// 用 Type alias
type Person = {
  name: string;
  age: number;
};

function greet(person: Person) {
  return 'Hello ' + person.name;
}

Property Modifiers

Optional Properties

可选属性

ts
interface PaintOptions {
  shape: Shape;
  xPos?: number;
  yPos?: number;
}

function paintShape(opts: PaintOptions) {
  let xPos = opts.xPos; // number | undefined
  let xPos = opts.yPos; // number | undefined
}

const sharp = getSharp();
paintShape({ sharp });
paintShape({ sharp, xPos: 100 });
paintShape({ sharp, yPos: 100 });
paintShape({ sharp, xPos: 100, yPos: 100 });

使用时可以为 undefined

ts
// undefined 检查
function paintShape(opts: PaintOptions) {
  let xPos = opts.xPos === undefined ? 0 : opts.xPos; // number
  let xPos = opts.yPos === undefined ? 0 : opts.yPos; // number
}

// 解构 + 默认值
function paintShape({ sharp, xPos = 0, yPos = 0 }: PaintOptions) {
  console.log('x coordinate at', xPos); // number
  console.log('y coordinate at', yPos); // number
}

readonly Properties

ts
interface SomeType {
  readonly prop: string;
}

function doSomething(obj: SomeType) {
  // 可读
  console.log(`prop has the value '${obj.prop}'.`);

  // 只读,不能赋值
  obj.prop = 'hello'; // Error
}

Index Signatures

索引签名:有时候不提前确定属性名

ts
interface StringArray {
  [index: number]: string;
}

const myArray: StringArray = getStringArray();
const secondItem = myArray[1];

可以用于索引签名的类型:string, number, symbol, template string patterns, and union types consisting only of these.

成员有两种访问方式:obj.propertyobj["property"],会和索引签名冲突† 当你声明一个索引签名时,所有明确的成员都必须符合索引签名:

ts
interface NumberDictionary {
  [index: string]: number;

  length: number; // Ok
  name: string; // Error:和索引签名返回类型不符合
}

// 修改索引签名,返回联合类型
interface NumberOrStringDictionary {
  [index: number]: number | string;
  length: number; // Ok
  name: string; // Ok
}

Excess Property Checks

陷入到过量属性检查的原因:

  • 一些是 bug
  • 一些是类型定义有问题

解决方式:类型断言、索引签名

ts
interface SquareConfig {
  color?: string;
  width?: number;
}

function createSquare(config: SquareConfig): { color: string; area: number } {
  return {
    color: config.color || 'red',
    area: config.width ? config.width * config.width : 20,
  };
}

// color/colour问题
// Error: 'colour' does not exist in type 'SquareConfig'
let mySquare = createSquare({ colour: 'red', width: 100 }); 

Extending Types

拓展类型

ts
// 单继承
interface BasicAddress {
  name?: string;
  street: string;
  city: string;
  country: string;
  postalCode: string;
}

interface AddressWithUnit extends BasicAddress {
  unit: string;
}

// 多继承
interface Colorful {
  color: string;
}

interface Circle {
  radius: number;
}

interface ColorulCircle extends Colorful, Circle {}

const cc: ColorfulCircle = {
  color: 'red',
  radius: 42,
};

Intersection Types

ts
interface Corlorful {
  color: string;
}
interface Circle {
  radius: number;
}

type ColorfulCircle = Colorful & Circle;

function draw(circle: Colorful & Circle) {
  console.log(`Color was ${circle.color}`);
  console.log(`Radius was ${circle.radius}`);
}

draw({ color: 'blue', radius: 42 }); // Ok
draw({ color: 'red', raidus: 42 }); // Error: 'raidus' does not exist in type 'Colorful & Circle'