包含知识点:静态类型、类型注解、类型推断、泛型、类型定义文件、模块化、打包编译、装饰器、Metadata(元数据)、设计模式html
推荐使用VSCode
编辑器。由于TS
和VSCode
都是微软推出的。VSCode
作了不少对TS
的适配。前端
参考文档:node
定义: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'
}
复制代码
参考文档: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})
复制代码
优点:设计模式
参考文档:数组
// 安装TS
npm install typescript -g
tsc demo.ts 就生成了demo.js文件
node demo.js // 运行生成的文件
// 转化工具 简化上述过程
npm install -g ts-node
// 运行
ts-node demo.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
全部的属性和方法。数据结构
总结:咱们看到一个变量是静态类型,不只仅意味着这个变量的类型不能修改,还意味这个变量的属性和方法已基本肯定。编辑器
let count: number = 123
const personName: string = 'style'
复制代码
还有null, undefined, symbol, boolean, void
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
}
复制代码
let count: number;
复制代码
如上所示,显式声明变量类型的写法,称为类型注解。
let countInfernce = 123
const firstNumber = 1
const secondNumber = 2
const total = firstNumber + secondNumber
复制代码
在咱们写的代码中,变量并无使用类型注解,但并未报错,就是由于TS进行了类型推断。
若是TS会自动分析变量类型,咱们就什么都不须要作了。 若是TS没法分析变量类型的话,咱们就须要使用类型注释。
function getTotal(firstNumber: number, secondNumber: number) {
return firstNumber + secondNumber;
}
const total = getTotal(1, 2) // 此时就不须要写类型注解了
复制代码
如上所示,此时是须要些类型注解的。
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})
复制代码
基础类型 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'
复制代码
元组:规定了每个元素的类型。数量个数有限的数组,同时每一项的类型又是固定的形式。
数组例子:
数组有两种定义方式
方法一
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];
复制代码
元组常常用于CSV
、Excel
等类型的文件中
// 用元组处理CSV文件
const studentList: [string, string, number][] = [
['fruit', 'male', 18],
['bro', 'female', 26],
['jhon', 'female', 28],
]
复制代码
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', // 此种写法会报错,以下图
})
复制代码
接口中有方法
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
接口中
name
和
say
方法是必传的,类里面必须具有接口的属性。
下面的写法是正确的
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
}
复制代码
总结:
普通类
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
来调用。