首页 > 其他分享 >TS学习笔记(3)

TS学习笔记(3)

时间:2022-08-19 00:13:35浏览次数:106  
标签:name age number 笔记 TS 学习 Person 属性 string

在面向对象语言中,接口(Interfaces)是一个很重要的概念,它是对行为的抽象,而具体如何行动需要由类(classes)去实现(implement)。
TypeScript 中的接口是一个非常灵活的概念,除了可用于[对类的一部分行为进行抽象]以外,也常用于对「对象的形状(Shape)」进行描述。

在这里我们必须先要认识到 在es6的时候 js就已经引入了类这个概念 js中的java越来越得到了体现 现在ts把接口这个概念也补充进去了

讲道理我在学这个章节的时候 看着TS的代码 满脑子都是这TM不就是JAVA吗?

举个例子

interface Person {
    name: string;
    age: number;
}
let tom: Person = {
    name: 'Tom',
    age: 25
};

上面的例子中,我们定义了一个接口 Person,接着定义了一个变量 tom,它的类型是 Person。这样,我们就约束了 tom 的形状必须和接口 Person 一致。

接口一般首字母大写。

定义的变量比接口少了一些属性是不允许的:

interface Person {
    name: string;
    age: number;
}
let tom: Person = {
    name: 'Tom'
};

// index.ts(6,5): error TS2322: Type '{ name: string; }' is not assignable to type 'Person'.
//   Property 'age' is missing in type '{ name: string; }'.

多一些属性也是不允许的:

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

let tom: Person = {
    name: 'Tom',
    age: 25,
    gender: 'male'
};

// index.ts(9,5): error TS2322: Type '{ name: string; age: number; gender: string; }' is not assignable to type 'Person'.
//   Object literal may only specify known properties, and 'gender' does not exist in type 'Person'.

可见,赋值的时候,变量的形状必须和接口的形状保持一致

interface Person {
  readonly name: string;
  age?: number;
}

只读属性用于限制只能在对象刚刚创建的时候修改其值。此外 TypeScript 还提供了 ReadonlyArray<T> 类型,它与 Array<T> 相似,只是把所有可变方法去掉了,因此可以确保数组创建后再也不能被修改。

let a: number[] = [1, 2, 3, 4];
let ro: ReadonlyArray<number> = a;
ro[0] = 12; // error!
ro.push(5); // error!
ro.length = 100; // error!
a = ro; // error!

任意属性

有时候我们希望一个接口中除了包含必选和可选属性之外,还允许有其他的任意属性,这时我们可以使用 索引签名 的形式来满足上述要求。

interface Person {
    name: string;
    age?: number;
    [propName: string]: any;
}

let tom: Person = {
    name: 'Tom',
    gender: 'male'
};

需要注意的是,一旦定义了任意属性,那么确定属性和可选属性的类型都必须是它的类型的子集

interface Person {
    name: string;
    age?: number;
    [propName: string]: string;
}

let tom: Person = {
    name: 'Tom',
    age: 25,
    gender: 'male'
};

// index.ts(3,5): error TS2411: Property 'age' of type 'number' is not assignable to string index type 'string'.
// index.ts(7,5): error TS2322: Type '{ [x: string]: string | number; name: string; age: number; gender: string; }' is not assignable to type 'Person'.
//   Index signatures are incompatible.
//     Type 'string | number' is not assignable to type 'string'.
//       Type 'number' is not assignable to type 'string'.

上例中,任意属性的值允许是 string,但是可选属性 age 的值却是 numbernumber 不是 string 的子属性,所以报错了。

另外,在报错信息中可以看出,此时 { name: 'Tom', age: 25, gender: 'male' } 的类型被推断成了 { [x: string]: string | number; name: string; age: number; gender: string; },这是联合类型和接口的结合。

一个接口中只能定义一个任意属性。如果接口中有多个类型的属性,则可以在任意属性中使用联合类型:

interface Person {
    name: string;
    age?: number; // 这里真实的类型应该为:number | undefined
    [propName: string]: string | number | undefined;
}

let tom: Person = {
    name: 'Tom',
    age: 25,
    gender: 'male'
};

 

接口Interface与tpye类型的区别

TypeScript 的核心原则之一是对值所具有的结构进行类型检查。 而接口的作用就是为这些类型命名和为你的代码或第三方代码定义数据模型。

type(类型别名)会给一个类型起个新名字。 type 有时和 interface 很像,但是可以作用于原始值(基本类型),联合类型,元组以及其它任何你需要手写的类型。起别名不会新建一个类型 - 它创建了一个新 名字来引用那个类型。给基本类型起别名通常没什么用,尽管可以做为文档的一种形式使用。

有接口 当然就有类!

TypeScript 类

类的属性与方法

在面向对象语言中,类是一种面向对象计算机编程语言的构造,是创建对象的蓝图,描述了所创建的对象共同的属性和方法。

在 TypeScript 中,我们可以通过 Class 关键字来定义一个类:

 

class Greeter {
  // 静态属性
  static cname: string = "Greeter";
  // 成员属性
  greeting: string;

  // 构造函数 - 执行初始化操作
  constructor(message: string) {
    this.greeting = message;
  }

  // 静态方法
  static getClassName() {
    return "Class name is Greeter";
  }

  // 成员方法
  greet() {
    return "Hello, " + this.greeting;
  }
}

let greeter = new Greeter("world");

那么成员属性与静态属性,成员方法与静态方法有什么区别呢?这里无需过多解释,我们直接看一下以下编译生成的 ES5 代码: 

"use strict";
var Greeter = /** @class */ (function () {
    // 构造函数 - 执行初始化操作
    function Greeter(message) {
        this.greeting = message;
    }
    // 静态方法
    Greeter.getClassName = function () {
        return "Class name is Greeter";
    };
    // 成员方法
    Greeter.prototype.greet = function () {
        return "Hello, " + this.greeting;
    };
    // 静态属性
    Greeter.cname = "Greeter";
    return Greeter;
}());
var greeter = new Greeter("world");

访问器

在 TypeScript 中,我们可以通过 getter 和 setter 方法来实现数据的封装和有效性校验,防止出现异常数据。是不是有点像vue2.x中的响应式原理呢?

let passcode = "Hello TypeScript";

class Employee {
  private _fullName: string;

  get fullName(): string {
    return this._fullName;
  }

  set fullName(newName: string) {
    if (passcode && passcode == "Hello TypeScript") {
      this._fullName = newName;
    } else {
      console.log("Error: Unauthorized update of employee!");
    }
  }
}

let employee = new Employee();
employee.fullName = "Semlinker";
if (employee.fullName) {
  console.log(employee.fullName);
}

类的继承

继承 (Inheritance) 是一种联结类与类的层次模型。指的是一个类(称为子类、子接口)继承另外的一个类(称为父类、父接口)的功能,并可以增加它自己的新功能的能力,继承是类与类或者接口与接口之间最常见的关系。

继承是一种 is-a 关系:


在 TypeScript 中,我们可以通过 extends 关键字来实现继承:
class Animal {
  name: string;
  
  constructor(theName: string) {
    this.name = theName;
  }
  
  move(distanceInMeters: number = 0) {
    console.log(`${this.name} moved ${distanceInMeters}m.`);
  }
}

class Snake extends Animal {
  constructor(name: string) {
    super(name);
  }
  
  move(distanceInMeters = 5) {
    console.log("Slithering...");
    super.move(distanceInMeters);
  }
}

let sam = new Snake("Sammy the Python");
sam.move();

 

 

标签:name,age,number,笔记,TS,学习,Person,属性,string
From: https://www.cnblogs.com/tomxiao/p/16600606.html

相关文章

  • 学习:python pyEmail邮件处理
    pyEmail邮件处理客户端1--微信服务器---客户端2客户端1(网易)---网易邮箱服务器---QQ邮箱服务器----客户端2(QQ邮箱)邮箱协议:smtp协议imap协议pop协议  本次用126邮箱......
  • Redis学习(2)set和zset
    set集合底层就是一个hash表,只不过保存的值是null。添加删除saddkeyelementelement...用element等创建一个setsmemberskey显示key中成员sismemberskeyelemen......
  • 学习:python 实用第三方模块
    baidu-aip人工智能算法ai:识别语音唤醒---语音识别(将语音转换为字符串)---执行指令ai.baidu.com可以访问百度AI开放平台了解相关内容例如:使用百度AI开放平台-通用文字......
  • 【PyTorch学习笔记】1.Tensor 与 Variable
    在PyTorch0.4.0之前,torch.autograd包中存在Variable这种数据类型,主要是用于封装Tensor,进行自动求导。Variable主要包含下面几种属性。 data:被包装的......
  • 学习笔记-涛讲F#(基础)
    目录简介类型推导多个输入参数的函数定义单位偏函数常量也是函数返回值(unit与ignore)函数串联实现“开方乘十”使用管道符|>元组(参数加上括号)F#中的类记录复制和更新记录表......
  • python学习Day48
    Day48今日内容概要Navicat可视化软件多表查询练习题python操作MySQL获取命令的执行结果SQL注入问题基础用户登录SQL语句(记忆)知识点额外补充今日内容详细......
  • Markdown学习
    Markdown学习标题井号+空格+标题名字回车(一级标题)注意:几级标题就用几个井号字体粗体:两边两个星号中间+文字hello,world!斜体:两边一个星号中间+文字hello,world!斜体......
  • 展昭老师接口测试笔记
     1. 接口测试常规操作入门2. 接口测试用例设计方法详解3. 用例设计秘笈之场景分析法详解4. 接口测试用例编写与执行实战5. 接口自动化测试执行实战展昭老师 安......
  • 2022-08-18 第五组 赖哲栋 学习笔记
    MySQL常用函数聚合函数count:计数count():MySQL对count()底层优化,count(0)count(1)count(主键)count(字段)min:最小值max:最大值sum:求和avg:平均值数值型函数......
  • 学习python-Day42
    今日学习内容Navicat可视化软件可以充当很多数据库软件的客户端,最主要的用于MySQL下载>>>正版收费>>>找破解版>>>百度查询下载完成后>>>连接>>>MySQL>>>创建连接......