【TypeScript】对象类型的定义

简言

在 JavaScript 中,我们分组和传递数据的基本方式是通过对象。在 TypeScript 中,我们通过对象类型来表示这些对象。
在这里插入图片描述

对象类型

在 JavaScript 中,我们分组和传递数据的基本方式是通过对象。在 TypeScript 中,我们通过对象类型来表示这些对象。
正如我们所看到的,它们可以是匿名的:

function greet(person: { name: string; age: number }) {
  return "Hello " + person.name;
}

或使用接口来命名:

interface Person {
  name: string;
  age: number;
}
 
function greet(person: Person) {
  return "Hello " + person.name;
}

又或者使用别名:

type Person = {
  name: string;
  age: number;
};
 
function greet(person: Person) {
  return "Hello " + person.name;
}

这三种方式都挺常见的,一般都是使用后两种,使用接口或别名来定义类型,简单明了,且易复用。

对象属性类型

对象类型中的每个属性都可以指定几件事:类型、属性是否可选以及属性是否可以写入,以及属性值。
定义规则如下:

  • 属性类型 – 一般是字符串类型的,如果想定义其他的类型,用方括号包裹定义属性索引修改。
  • 属性值 – 和普通的变量类型定义一样,如果提前定义好了属性值,则需要符合提前定义好的类型范围。
  • 可选属性 — 问号(?)定义。
  • 仅读属性 — 属性默认是可写入的,仅读属性需要 索引前面加 readonly 关键词。

示例:

interface Person {
  name: string;
  age: number;
}
type Shape = { kind: "circle" } | { kind: "square" };
interface PaintOptions {
  shape: Shape;
  xPos?: number;
  yPos?: number;
}

interface ReadonlyPerson {
  readonly name: string;
  readonly age: number;
}

let writablePerson: Person = {
  name: "Person McPersonface",
  age: 42,
};

// works
let readonlyPerson: ReadonlyPerson = writablePerson;

console.log(readonlyPerson.age); // prints '42'
writablePerson.age++;
console.log(readonlyPerson.age); // prints '43'

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

const myArray: StringArray = ['1','2'];
const secondItem = myArray[1];

对象索引类型

使用方括号包含索引index属性定义。

interface NumberOrStringDictionary {
  [index: string]: number | string;
  length: number; // ok, length is a number
  name: string; // ok, name is a string
}

上面提前定义了属性索引类型和属性值类型,不好扩展,也可以不指定属性值,即将属性值定义为any(任何类型):

interface SquareConfig {
  [index: string]: any;
  color?: string;
  width?: number;
}

可以在索引属性前加readonly,这样属性值不可修改:

interface ReadonlyStringArray {
  readonly [index: number]: string;
}
 
let myArray: ReadonlyStringArray = getReadOnlyStringArray();
myArray[2] = "Mallory";	//	报错

接口继承

使用接口定义的对象类型,可以使用关键词extends来继承其他接口。

interface Colorful {
  color: string;
}
 
interface Circle {
  radius: number;
}
 
interface ColorfulCircle extends Colorful, Circle {}
 
const cc: ColorfulCircle = {
  color: "red",
  radius: 42,
};

类型组合

接口允许我们通过扩展其他类型来创建新类型。TypeScript 提供了另一种称为交叉类型的结构,主要用于组合现有的对象类型。
组合类型是使用 & 运算符定义的。

interface Colorful {
  color: string;
}
interface Circle {
  radius: number;
}

type ColorfulCircle = Colorful & Circle;

type c1 = Colorful
type c2 = Circle

type c3 = c1 & c2 // Colorful & Circle

类似于数学中的并集运算。

泛型对象类型

可以使用泛型,来定义通用的对象类型。

interface Box<Type> {
  contents: Type;
}
//	别名也可以使用泛型
type OrNull<Type> = Type | null;
 
type OneOrMany<Type> = Type | Type[];
 
type OneOrManyOrNull<Type> = OrNull<OneOrMany<Type>>;

使用时,指定Type具体的类型值,其contents属性即可动态改变。

let box: Box<string>;

将 Box 视为真实类型的模板,其中 Type 是一个占位符,将被其他类型替换。当 TypeScript 看到 Box<string> 时,它会用 string 替换 Box<Type> 中 Type 的每一个实例,并最终使用 { contents: string } 这样的代码。

元组对象类型

元组有的时候在表示列表对象类型时特别适合。

function doSomething(stringHash: [string, number]) {
  const [inputString, hash] = stringHash;
 
  console.log(inputString);
                 
  console.log(hash);
}

元组也可以使用剩余元素,但必须是数组/元组类型。

type StringNumberBooleans = [string, number, ...boolean[]];
type StringBooleansNumber = [string, ...boolean[], number];
type BooleansStringNumber = [...boolean[], string, number];

为什么可选元素和剩余元素会有用?因为它允许 TypeScript 将元组与参数列表对应起来。元组类型可用于其余参数和参数,因此:

function readButtonInput(...args: [string, number, ...boolean[]]) {
  const [name, version, ...input] = args;
  // ...
}
//	相当于
function readButtonInput2(name: string, version: number, ...input: boolean[]) {
  // ...
}

结语

结束了。

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ZSK6

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值