TypeScript笔记

117 阅读4分钟

typescript

一:概念

javascript为基础构建的语言,一个javascript的超集

二:环境搭建

1: 安装nodejs

2: 全局安装ts

npm i typescript -g

3: 编译ts文件

tsc xxx.ts

三:类型

1:类型声明

let a: number;
a = 10;
a = 'amrt'; 			// 报错提示
function sum(a: number, b: number): number {
  return a + b;
}

2:字面量

let a: 10;
a = 10;
let a: 'hello';
a = 'ee'      // 报错

3:联合

let a: number | boolean;
a = 10;
a = true;

4:any

表示任意类型,一个类型设置any等于对该变量关闭TS的类型检测

声明变量不指定类型,则TS解析会自动判断变量为any(隐式any)

let b: any;
b = 10;
b = 'hello';

5:unknown

表示未知的类型,实际上是一个类型安全的any,不能直接赋值给其他变量

let c: unknown;
c = 10;
c = 'hell0';
s = e    // 报错

6 :断言

可以告诉解析器变量的实际类型

s = e as string;
s = <string>e;

7:void

用来表示空,以函数为例,表示函数没有返回值

function fn(): void {
    
}

8:never

表示永远不会返回结果

function fn1(): never {
	throw new Error('报错了');
}

9:object

{} 用来指定对象中可以包含哪些属性

在属性名后加?,表示属性可选

let a: object;
a = {};

let b: {name: string, age?: number};
b = {name: '孙悟空'}

// 表示任意类型属性
let c: {name: string, [propName: string]: any};

10:Function

设置函数结构类型声明

let d: (a: number, b: number) => number

11:Array

let e: string[];   // 表示字符串数组
e = ['a','b','c'];

let g: Array<number>; // 表示数字数组
g = [1,2,3];

12:元组(tuple)

表示固定长度的数组

let h: [string,string];
h = ['hello','abc'];

13:枚举(enum)

Enum Gender{
    Male,
    Female 
}
let i: {name: string, gender: Gender};
i = {
	name: '孙武',
    gender: Gender.Male
}
console.log(i.gender === Gender.Male)

14:类型别名

type myType = 1 | 2 | 3 | 4;
let k: myType;

三:编译

1: 生成tsconfig.json

tsc -init
"include": [ './src/**/*'] // 编译包含
"exclude": ['./src/**/*'] // 编译不包含
"compilerOptions":{
    "target": "es2016", // 编译版本js
    "module": "commonjs", // 指定使用模块化的规范
    "lib": ["dom"], // 用来指定项目中使用的库
    "outDir": "./", // 指定编译文件所在的目录
    "outFile": "./", // 将所有全局作用域代码合并为一个文件
    "allowJs": false, // 是否对js文件进行编译,默认false
    "checkJs": false, // 检查js是否符合语法
    "removeComments": true, // 是否移除注释
    "noEmit": true, // 不生成编译后的文件
    "noEmitOnError": true, // 报错时不生成编译后的文件
    "alwaysStrict": true, // 用来设置编译后的文件是否使用严格模式
    "noImplicitAny": true, // 不允许隐式any类型
    "noImplicitThis": true, // 不允许不明确的this
    "strictNullChecks": true, // 严格检查空值
    "strict": true, // 所有严格检查的总开关
}

四:高级

1:类

class Peson {
    // 定义实例属性
    name: string = '孙悟空';
    // 静态属性
    static age: number = 18;
    // 只读
    readonly name: string = '孙悟空';
    // 定义方法
    sayHello() {
        console.log('hello');
    }
    // 构造器
    constructor(name: string, age: number) {
        this.name = name;
        this.age = age;
    }
}
// 继承
class Person1 extends Person {
    // 子类会拥有父类的属性和方法
    // 子类方法可重写父类的方法
    constructor() {
        super(); // 调用父类的构造函数
    }
}

2:抽象类

以abstract开头的类为抽象类,不能用来被创建对象,只能用来被继承

abstract class Animal {
    // 定义抽象方法,没有方法体,子类必须对其重写
    abstract sayHello(): void;
}
class Dog extends Animal {
    
}

3:接口

用来定义一个类的结构,应该包含哪些属性与方法,同时接口也可以当成类型声明去使用,接口中所有属性都不能有实际值,在接口中的所有方法都是抽象方法

interface myInter {
    name: string;
    sayHello(): void;
}
// 定义类时,可以使类去实现一个接口,实现接口就是使类满足接口的要求
class MyClass implements myInter {
    name: string;
    constructor(name: string) {
        this.name = name;
    }
    sayHello() {
        console.log('大家好')
    }
}

4:属性封装

public: 公共属性,可以在任意位置访问(修改),默认。

private: 私有属性,只能在类的内部进行访问,通过在类中添加方法使私有属性可以被外部访问。

protected: 受保护的属性,只能在当前类和当前子类中访问(修改)。

class MyClass {
    private: _name: string;
	// 设置getter
	get name() {
        return this._name;
    }
	set name(value: string) {
        this._name = value;
    }
}
const cl = new MyClss(name: '孙悟空');
cl.name = '猪八戒';
console.log(cl.name)
class C {
    // 可以直接将属性定义在构造函数中
    constructor(public name: string, public age: number) {
        
    }
}

5:泛型

在定义函数或者类时,如果遇到类型不明确就可以使用泛型。

function fn<T>(a: T): T {
  return a;
}
// 可以直接调用具有泛型的函数
fn(a: 10); // 不指定泛型,Ts自动推断
fn<string>(a: 'hello'); // 指定泛型

// 泛型指定多个
function fn2<T, K>(a: T, b: K): T {
  return a;
}
fn2<number,string>(a: 123, b: 'hello');

// 表示泛型T必须是Inter的实现类(子类)
interface Inter {
  length: number;
}
function fn3<T extends Inter>(a: T): number {
  return a.length;
}