TypeScript入门篇(一)

1、还不抓紧学习TS?

  1. TS是JS的超集,是创建在JS上的一门语言。
  2. TS可使用JS以外的扩展语法、面向对象、静态类型。
  3. TS基础语法 -- 爬虫功能开发 -- TS语法进阶 -- 项目接口开发 -- TS高级语法 -- 项目代码重构 -- 项目前端开发 -- 总结

包含知识点:静态类型、类型注解、类型推断、泛型、类型定义文件、模块化、打包编译、装饰器、Metadata(元数据)、设计模式html

2、TS基础语法

1. TS的定义

推荐使用VSCode编辑器。由于TSVSCode都是微软推出的。VSCode作了不少对TS的适配。前端

参考文档:node

  1. www.tslang.cn/docs/home.h…
  2. www.typescriptlang.org/

定义:TypeScript is a typed superset of JavaScript that compiles to plain JavaScript.TS是JS的超集,被编译为JS以后才能够运行。TS是静态代码类型typescript

// ts文件
let a = 123
a = '123'  // 不能将类型“"123"”分配给类型“number”。由于其为静态类型,所以不能从number类型变为string类型。

标准写法
let a: number = 123
复制代码
interface Person {
  name: string
}

const teacher: Person = {
  name: 'Fruit Bro'
}
复制代码

2. TS的优点

参考文档:7 个不使用 TypeScript 的理由npm

interface Point {
  x: number,
  y: number,
}
function tsDemo (data: Point) {
  return Math.sqrt(data.x ** 2 + data.y ** 2)
}

tsDemo({x: 1, y: 2})
复制代码

优点:设计模式

  1. 开发过程当中,发现潜在问题。
  2. 更友好的编辑器自动提示。
  3. 代码语义更清晰易懂。

3. TS基础环境搭建

参考文档:数组

  1. nodejs.org/
  2. nodejs.cn/

// 安装TS
npm install typescript -g 

tsc demo.ts 就生成了demo.js文件
node demo.js // 运行生成的文件

// 转化工具 简化上述过程
npm install -g ts-node
// 运行
ts-node demo.ts
复制代码

4. TS静态类型理解

// count为number类型以后,会具有number类型的全部属性和方法
const count: number = 2020 

复制代码

count.提示的都是number类型所对应的方法,以下图: bash

// 自定义类型

interface Point {
  x: number,
  y: number,
}

const point: Point = {
    x: 1,
    y: 2
}
复制代码

所以point变量具有Point全部的属性和方法。数据结构

总结:咱们看到一个变量是静态类型,不只仅意味着这个变量的类型不能修改,还意味这个变量的属性和方法已基本肯定编辑器

5. TS基础类型和对象类型

  1. 基础类型
let count: number = 123
const personName: string = 'style'
复制代码

还有null, undefined, symbol, boolean, void

  1. 对象类型
const teacher: {
  name: string,
  age: number,
} = {
  name: 'fruit',
  age: 18,
}
// 数组
const numbers: number[] = [1, 2, 3]

// 类
class Person {}
const fruit: Person = new Person() // fruit必须是个person类

// function, 返回值为number的函数
const getTotal: () => number = () => {
  return 123
}
复制代码

6. TS类型注解(type annotation)和类型推断(type inference)

let count: number;
复制代码

如上所示,显式声明变量类型的写法,称为类型注解

let countInfernce = 123
const firstNumber = 1
const secondNumber = 2
const total = firstNumber + secondNumber
复制代码

在咱们写的代码中,变量并无使用类型注解,但并未报错,就是由于TS进行了类型推断。

如上所示, 咱们并未定义变量类型,TS会自动的去尝试分析变量的类型,称为类型推断

若是TS会自动分析变量类型,咱们就什么都不须要作了。 若是TS没法分析变量类型的话,咱们就须要使用类型注释。

function getTotal(firstNumber: number, secondNumber: number) {
  return firstNumber + secondNumber;
}

const total = getTotal(1, 2) // 此时就不须要写类型注解了
复制代码

如上所示,此时是须要些类型注解的。

7. 函数相关类型

function add(first: number, second: number): number { // 定义返回类型
  return first + second
}
const total = add(1, 2)

// 若是不定义返回类型,以下写法不会报错
function add(first: number, second: number) { // 未定义返回类型
  return first + second + '' // 返回字符串
}
const total = add(1, 2)
复制代码
function sayHello (): void { // 无返回值void
  console.log('hello')
}
复制代码
// never:这个函数永远不会执行到最后,以下两种状况
function errorEmitter (): never {
  throw new Error()
  console.log('123')
}
function errorEmitter (): never {
  while(true) {}
}
复制代码

解构赋值的类型写法:

状况1:
function add({ first, second }: {first: number, second: number}): number {
  return first + second
}
const total = add({first: 1, second: 2})

状况2:
function getNumber ({first}: {first: number}) {
  return first
}
const count = getNumber({first: 1})
复制代码

8. TS基础语法

基础类型 boolean、number、string、void、symbol、undefined、null

对象类型 {}、function、[]、class

上图说明,若是声明和赋值放在两行写,则没法推断出变量类型。所以就须要类型注解。

函数写法1
const func = (str: string): number => {
  return parseInt(str, 10)
}
函数写法2
const func: (str: string) => number = (str) => {
  return parseInt(str, 10)
}
复制代码

如上图,提示了函数的类型。
如上图,能够不用写返回值,能够用类型推断。

如上图,自动推断出 Date类型。

const rawData = '{"name": "fruit"}'
const newData = JSON.parse(rawData) // JSON.parse返回的内容并不能帮助TS推断newData的类型
复制代码

以下图,newData为any

所以能够改成以下写法:

interface Person {
  name: string
}
const rawData = '{"name": "fruit"}'
const newData: Person = JSON.parse(rawData)
复制代码

更多类型

let temp: number | string = 123 // temp变量有可能为number或string
temp = '456'
复制代码

9. TS数组和元组

元组:规定了每个元素的类型。数量个数有限的数组,同时每一项的类型又是固定的形式

数组例子

数组有两种定义方式

方法一
let list: number[] = [1, 2, 3]
方法二
let list: Array<number> = [1, 2, 3]
复制代码

基础类型

// 所有为number类型
const numberArr: number[] = [1, 2, 3]
// 为number或string
const numberArr: (number | string)[] = [1, '2', 3]
// 所有为string类型
const stringArr: string[] = ['a', 'b', 'c']
// 所有为undefined类型
const undefinedArr: undefined[] = [undefined]
复制代码

对象类型

const objectArr: {name: string, age: number}[] = [{name: 'fruit', age: 18}]
复制代码

也能够用类型别名

// type alias 类型别名,使用type关键字来定义
type User = {name: string, age: number}

const objectArr: User[] = [{name: 'fruit', age: 18}]

// 使用class
class Student {
  name: string;
  age: number;
}
const objectArr: Student[] = [
  new Student(),
  {  // 数据结构与Student保持一致也能够
      name: 'fruit', 
      age: 18
  }
]
复制代码

元组例子

// 元组 tuple
const teacherInfo: [string, string, number] = ['Fruit', 'male', 18];
复制代码

元组常常用于CSVExcel等类型的文件中

// 用元组处理CSV文件
const studentList: [string, string, number][] = [
  ['fruit', 'male',   18],
  ['bro',   'female', 26],
  ['jhon',  'female', 28],
]
复制代码

9. TS的Interface接口

interface Person {
  name: string;
}

const getPersonName = (person: Person) => {
  console.log(person.name);
};

const setPersonName = (person: Person, name: string) => {
  person.name = name;
};
复制代码

用类型别名也能够

type Person = {
  name: string;
}

const getPersonName = (person: Person) => {
  console.log(person.name);
};

const setPersonName = (person: Person, name: string) => {
  person.name = name;
};
复制代码

interface接口与type类型别名的区别: type Person = string,type能够直接表明string,但interface只能表明一个对象或函数,没办法表明基础类型。规范:能用接口的尽可能用接口表示,实在无法表示再用类型别名。

interface Person {
  readonly name: string; // 只读
  age?: number; // 可选属性
  [propName: string]: any; // 除了name和age外,还能够有其余属性,此属性名为字符串类型,属性值为任何类型
}

const getPersonName = (person: Person): void => {
  console.log(person.name);
};

const setPersonName = (person: Person, name: string): void => {
  person.name = name; // name为只读后,将不能赋值
};

const person = {
  name: 'fruit',
}

getPersonName(person)
setPersonName(person, 'bro')
复制代码
第一种
const person = {
  name: 'fruit',
  sex: 'male',
}

getPersonName(person)
第二种
const person = {
  name: 'fruit',
  sex: 'male',
}

getPersonName({
  name: 'fruit',
  sex: 'male', // 此种写法会报错,以下图
})
复制代码

缘由:当以字面量的形式(第二种写法)传入的时候,TS会对此对象进行强校验。以变量的形式传入,则不会这么严格(第一种写法)。

接口中有方法

interface Person {
  name: string;
  age?: number;
  [propName: string]: any; // 除了name和age外,还能够有其余额外属性,此属性名为字符串类型,属性值为任何类型
  say(): string; // 接口中有say方法,返回值为string类型
}

const getPersonName = (person: Person): void => {
  console.log(person.name);
}

const person = {
  name: 'fruit',
  sex: 'male',
  say() { // 方法
    return 'say hello' // 返回值
  }
}

getPersonName(person)
复制代码

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

class User implements Person { // 类User应用Person接口

}
复制代码

此时会报上述错误,由于 Person接口中 namesay方法是必传的,类里面必须具有接口的属性。

下面的写法是正确的

class User implements Person {
  name =  'fruit'
  say() {
      return 'hello fruit'
  }
}
复制代码

接口的继承

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

interface Student extends Person { // Student继承Person,并增长本身的方法study
  study(): string
}
复制代码

函数的类型声明定义

interface SayHi { // 函数的类型声明
  (word: string): string // 接收string类型的参数,同时返回值为string
}

const say: SayHi = (word: string) => {
  return word
}
复制代码

总结:

  1. interface和type相相似,但不彻底一致。
  2. readonly 只读属性、?可选参数、propName 额外属性、say()方法属性
  3. extends 接口继承
  4. 接口可直接定义具体的方法类型
  5. implements 用来作class类的属性约束
  6. 接口就是在咱们开发的过程当中帮助咱们作语法提示的工具,编译后接口和类型所有剔除掉,并不会变成js代码

10. TS中类的定义与继承

普通类

class Person1 {
  name = 'fruit';
  getName() {
    return this.name;
  }
}

const person2 = new Person1();
console.log(person2.getName()); // fruit
复制代码

普通类继承

class Teacher extends Person1 {
  getTeacherName() {
    return 'Bro';
  }
}

const teacher1 = new Teacher();
console.log(teacher1.getName()); // fruit
console.log(teacher1.getTeacherName()); // Bro
复制代码

类的重写

class Teacher extends Person1 {
  getTeacherName() {
    return 'Bro';
  }
  getName() { // 重写getName
    return 'Fruit'
  }
}

const teacher1 = new Teacher();
console.log(teacher1.getName()); // Fruit
console.log(teacher1.getTeacherName()); // Bro
复制代码

super关键字

class Teacher extends Person1 {
  getTeacherName() {
    return 'Bro';
  }
  getName() { // 重写getName
    return super.getName() + 'bro' // 使用super关键字,调用父类的方法
  }
}

const teacher1 = new Teacher();
console.log(teacher1.getName()); // fruitbro
复制代码

super通常用来作什么:当一个类把父类的方法覆盖(重写)掉以后,此时还想调用父类的方法,此时可经过super来调用。

相关文章
相关标签/搜索