翼度科技»论坛 编程开发 JavaScript 查看内容

[TS手册学习] 04_对象类型

4

主题

4

帖子

12

积分

新手上路

Rank: 1

积分
12
TS官方手册:TypeScript: Handbook - The TypeScript Handbook (typescriptlang.org)
匿名与具名

对象类型的声明可以是匿名的,也可以使用interface或type进行具名声明。
  1. function greet(person: { name: string; age: number }) {
  2.   return "Hello " + person.name;
  3. }
复制代码
  1. interface Person {
  2.   name: string;
  3.   age: number;
  4. }
  5. function greet(person: Person) {
  6.   return "Hello " + person.name;
  7. }
复制代码
  1. type Person = {
  2.   name: string;
  3.   age: number;
  4. };
  5. function greet(person: Person) {
  6.   return "Hello " + person.name;
  7. }
复制代码
可选属性 optional

使用?标记:
  1. interface PaintOptions {
  2.   shape: Shape;
  3.   xPos?: number;
  4.   yPos?: number;
  5. }
复制代码
注:使用PaintOptions声明的对象,它的xPos属性会被初步推断为number | undefined类型。
可以使用条件语句或者解构+默认值的方式收束类型,排除undefined的情况:
  1. function paintShape(opts: PaintOptions) {
  2.     let xPos = opts.xPos === undefined ? 0 : opts.xPos;
  3.     // xPos 的类型为number
  4. }
复制代码
  1. function paintShape({ shape, xPos = 0, yPos = 0 }: PaintOptions) {
  2.         // xPos 的类型为number,因为undefined会被默认值0取代
  3.     console.log("x coordinate at", xPos);
  4. }
复制代码
只读属性 readonly
  1. interface SomeType {
  2.     readonly prop: string;
  3. }
复制代码
注:如果有一个属性的值是引用值,例如一个对象或数组,且这个属性被标记为只读(readonly),我们不能修改它的引用值,但是可以修改它的内部属性。
  1. interface Home {
  2.   readonly resident: { name: string; age: number };
  3. }
  4. function visitForBirthday(home: Home) {
  5.   // 我们可以读取并且更新'home.resident'里的属性
  6.   console.log(`Happy birthday ${home.resident.name}!`);
  7.   home.resident.age++;
  8. }
  9. function evict(home: Home) {
  10.   // 但我们不能更新'home.resident'本身
  11.   home.resident = {
  12. Cannot assign to 'resident' because it is a read-only property.
  13.     name: "Victor the Evictor",
  14.     age: 42,
  15.   };
  16. }
复制代码
索引签名 index signatures
  1. interface StringArray {
  2.   [index: number]: string;
  3. }
  4. const myArray: StringArray = getStringArray();
  5. const secondItem = myArray[1];
复制代码
索引的类型只能是:string,number,symbol,以及与这些类型相关的联合类型。
通常只会考虑string和number类型的索引。
:可以同时支持string,number两种类型的索引器,但数字索引器返回的类型必须是字符串索引器返回类型的子类型。这是因为当使用数字进行索引时,JS 实际上会在索引到对象之前将其转换为字符串。于是使用100和"100"进行索引的结果是一样的。
当指定string类型索引的类型为S后,所有属性的类型都需要是S的子集。
  1. interface NumberDictionary {
  2.     [index: string]: number;
  3.     length: number; // ok
  4.     name: string; // NOT ok
  5. }
复制代码
这是因为当我们访问obj.a的时候,其实也是在访问obj["a"]。
在上面这个例子中,string类型索引被声明为number类型,这意味着这个对象的所有属性都是number类型,而下方name却被声明为string类型,矛盾了。
可以使用联合类型解决这个问题:
  1. interface NumberDictionary {
  2.     [index: string]: number | string;
  3.     length: number; // ok
  4.     name: string; // ok
  5. }
复制代码
同时,索引签名也可以设置为只读:
  1. interface ReadonlyStringArray {
  2.   readonly [index: number]: string;
  3. }
复制代码
类型继承

使用extends,支持多继承:
  1. interface Colorful {
  2.     color: string;
  3. }
  4. interface Circle {
  5.     radius: number;
  6. }
  7. interface ColorfulCircle extends Colorful, Circle {}
  8. const cc: ColorfulCircle = {
  9.     color: "red",
  10.     radius: 42,
  11. };
复制代码
交集类型 intersection types

使用&运算符获取已知的两个类型的交集。
  1. interface Colorful {
  2.   color: string;
  3. }
  4. interface Circle {
  5.   radius: number;
  6. }
  7. type ColorfulCircle = Colorful & Circle;
复制代码
将两个基本数据类型取交集会得到never。
类型继承 VS 交集类型
二者都可以产生更复杂的类型。
前者是在原有的类型的基础上添加可能未有的属性形成新属性,而后者将已有的类型进行组合。
泛型对象类型 Generic Object Types
  1. interface Box<Type> {
  2.   contents: Type;
  3. }
  4. let box: Box<string>;
复制代码
也可以与泛型函数结合使用:
  1. function setContents<Type>(box: Box<Type>, newContents: Type) {
  2.   box.contents = newContents;
  3. }
复制代码
除了使用interface,也可以使用type别名定义泛型类型。interface一般用来声明对象类型,而type更灵活,可以组合多种类型:
  1. type OrNull<Type> = Type | null;
  2. type OneOrMany<Type> = Type | Type[];
  3. // type OneOrManyOrNull<Type> = OneOrMany<Type> | null
  4. type OneOrManyOrNull<Type> = OrNull<OneOrMany<Type>>;
  5. // type OneOrManyOrNullStrings = OneOrMany<string> | null
  6. type OneOrManyOrNullStrings = OneOrManyOrNull<string>;
复制代码
来源:https://www.cnblogs.com/feixianxing/p/typescript-handbook-object-type-optional-readonly-index-signatures-extends-intersection-generic.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具