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;
}