Skip to content

ts

安装和配置

安装

shell
npm i -g typescript

编译ts文件为js

shell
tsc hello.ts

tsc --init生成配置文件

text
"module": "commonjs", //ES6
"target": "es2016",  //ES2015会有var
"outDir": "./", //编译出来的js文件目录
"include":["hello.ts"]

自动生成.d.ts文件,让ts可以直接引入js,或者安装引用的@types库,比如@types/jquery

text
"declaration": true,

详解tsconfig.json配置

json
{
  compilerOptions: {},//编译选项
  "file":[],//包含在程序中的文件允许列表
  "extends": "",//继承另一个配置文件
  "include":[],//指定的进行编译解析
  "exclude":[],//指定的不进行编译解析
  "references":[],//项目引用,提升性能
}

类型

基本类型

stingnumberboolean
symbolbigint
nullundefined

对象类型

[]{}function(){}

数组[]

数组类型
ts
let arr1: (number|string)[] = [1, 2, 3, 'hello'];
//或者
let arr2: Array<number|string> = [1, 2, 3,'hello'];
元组类型
ts
let arr3: [number,number, string] = [1, 2, 'hello',];
初始化空[]
ts
let arr:number[]=[] //数组默认支持(空不报错)

对象{}

普通对象
ts
type A = {
    username:string,
    age:number
}
let a:A = {
    username:'zhangsan',
    age:12
}
不确定对象元素?
ts
type A = {
    username:string,
    age?:number // 可以没有age
}
let a:A = {
    username:'zhangsan',
}
索引签名
ts
type A = {
[index:string]:any//索引签名,对象任意扩展
}
let a:A = {
    username:'zhangsan',
    age:10
}
初始化空对象
ts
type Obj = {username: string}
let obj = {} as Obj;
写出json
ts
let json: {username: string, age: number}[] = [{username:'zhangsan',age:12}];

function(){}

约定返回值
ts
//TS中要求:实参的个数跟形参的个数必须相同返回值为number
function foo(n: number, m?: string): number{
  return 123;
}

foo(123, 'hello');
ts
let foo: (n: number, m: string) => number = function(n, m){
    return 123;
}
等价
let foo1 = function (n: number, m: string): number{
    return 123;
}
没有返回值
ts
function foo(n: number, m?: string): void{//void没有返回值
}
重载
ts
//限制参数个数
function foo(n1: number): any
function foo(n1: number, n2: number): any
function foo(n1: number, n2: number, n3: number, n4: number): any
function foo(n1: number, n2?: number, n3?: number, n4?: number){
}
foo(1);
foo(1, 2);
foo(1, 2, 3);//报错
foo(1, 2, 3, 4);
ts
//限制请求参数,要么都是数字,要么都是字符
function foo(n: number, m: number): any
function foo(n: string, m: string): any
function foo(n: number|string, m: number|string){

}
foo(1, 2);
foo('a', 'b');
foo(3, 'c');//报错
可调用注解
ts
//限制请求参数,要么都是数字,要么都是字符
type A = {
    (n: number, m: number): any
    (n: string, m: string): any
}
function foo(n: number|string, m: number|string){}
let a: A = foo;
a('a','a')
a(1,1)

TS新增类型

anyneverunknowvoidenum

any

可以存任意类型、可以给任意变量赋值

ts
let a: any = 'hello';
a = 123;
a = true;
let aa:number = a //赋值给任意类型

unknow

可存任意类型,不可给变量赋值

ts
let b:unknown =['a','b']
b = 'abc'
b = true
let bb:number = b //报错

enum

自动累加&反向映射
ts
// 数字会反向映射
enum Roles {
    SUPER_ADMIN,
    ADMIN,
    USER
}
console.log(Roles.SUPER_ADMIN)//0
console.log(Roles.ADMIN)//1
console.log(Roles.USER)//2
console.log(Roles[0])//SUPER_ADMIN
console.log(Roles[1])//ADMIN
console.log(Roles[2])//USER
ts
// 枚举设置字符串,没有映射
enum Roles {
    SUPER_ADMIN="SUPER_ADMIN",
    ADMIN="ADMIN",
    USER="USER"
}
console.log(Roles.SUPER_ADMIN)//SUPER_ADMIN
console.log(Roles.ADMIN)//ADMIN
console.log(Roles.USER)//USER
console.log(Roles[0])//报错
console.log(Roles[1])//报错
console.log(Roles[2])//报错
const优化
ts
// const可直接返回,优化性能
const enum Roles {
    SUPER_ADMIN="SUPER_ADMIN",
    ADMIN="ADMIN",
    USER="USER"
}
console.log(Roles.SUPER_ADMIN)
enum Roles1 {
    SUPER_ADMIN="SUPER_ADMIN",
    ADMIN="ADMIN",
    USER="USER"
}
console.log(Roles1.SUPER_ADMIN)

console.log("SUPER_ADMIN" );//const可直接返回,优化性能
//没有const则会返回一堆代码
var Roles1;
(function (Roles1) {
    Roles1["SUPER_ADMIN"] = "SUPER_ADMIN";
    Roles1["ADMIN"] = "ADMIN";
    Roles1["USER"] = "USER";
})(Roles1 || (Roles1 = {}));
console.log(Roles1.SUPER_ADMIN);

类型判断

类型注解与推断

ts
//类型注解
let a: string = 'hello'

type A = string;
let b: A = 'hello'

联合类型

ts
// 联合类型:类型之间进行或的操作
let a: string|number|boolean = 'hello';
a = 123;

交叉类型

ts
type A = {
  username: string
}
type B = {
  age: number
}
let a: A&B = { username: 'xiaoming', age: 20 }

类型和非空断言

ts
let a: unknown = 'hello';
(a as []).map(()=>{}) // 强制as断言成[],抑制错误
ts
let b: string|undefined = undefined;
b!.length// 非空断言,抑制错误

interface

与type相同点,都可作为类型

ts
type A ={
  readonly username: string,
  age?: number;
}
let a: A = {
  username: 'xiaoming'
}
a.username = 'xiaobai'//报错
ts
interface A {
  readonly username: string;
  age?: number;
}
let a: A = {
  username: 'xiaoming'
}
a.username = 'xiaobai'//报错

interface和type区别

只能对象

interface只能是对象,type可用基本类型

ts
type A = string;
interface B {};
interface C string;//报错

支持合并

interface能合并,type不行

ts
interface A {
  username: string;
}
interface A {
  age: number;
}
let a:A = {
    username:'zhangsan',
    age:12
}

支持继承

// interface支持继承,type不支持

ts

interface A {
  username: string
}
interface B extends A {
  age: number
}
let b: B = {
  username: 'xiaoming',
  age: 20
}

不支持映射

interface不支持映射,type支持

ts
type A = {
  [P in 'username'|'age']: string;
}

不支持交叉

ts
type A = {
  username: string
}
type B = {
  age: number
}
let a: A&B = { username: 'xiaoming', age: 20 }

typeOf与keyOf

ts
let a = 'hello';
type A = typeof a;   // string
ts
let obj: {
  username: 'xiaoming',
  age: 20
}

let a: keyof typeof obj = 'username'

类型保护

ts
// is类型谓词,它可以做到类型保护的
function isString(n: any): n is string{
  return typeof n === 'string';
}
function foo(n: string|number){
  if( isString(n) ){
    n.length
  }
}

泛型

泛型基本类型

ts
type A<T = string> = T //默认为string
let a: A = 'hello'
let b: A<number> = 123

泛型数组

ts
type MyArray<T> = T[];
let d: MyArray<number> = [1, 2, 3]

泛型函数

ts
function foo<T>(n: T){
}
foo<string>('hello');
foo(123);

泛型与接口结合使用

ts
interface A<T> {
  (n?: T): void
}
let foo: A<string> = (n) => {}
foo('hello')

泛型与class

ts
class Foo<T> {
  username!: T;
}
let f = new Foo<string>();
f.username = 'hello';

泛型与继承

ts
class Foo<T> {
  username!: T
}
class Baz extends Foo<string> {}
let f = new Baz()
f.username = 'hello'

泛型约束

ts
type A = {
    length: number
}
function foo<T extends A>(n: T) {}
foo(123) //报错,没有length属性
foo('hello')

类型兼容

ts
function foo(n: { username: string }) {}
foo({ username: 'xiaoming' }) // success
// foo({ username: 'xiaoming', age: 20 }) // 直接用不行
let a = { username: 'xiaoming', age: 20 }//用变量做兼容
foo(a) // success
ts
//原理
let aa: {username: string} = { username: 'xiaoming' };
let b: {username: string; age: number} = { username: 'xiaoming', age: 20 };
aa = b; // success
// b = aa;  // error

类型映射

原理

ts
//映射类型只能用别名实现,不能用接口来实现
type A = {
  username: string
  age: number
}
type B<T> = {
   [P in keyof T]: T[P]
}
type C = B<A>//直接复制A的类型

ts方法

ts
type A = Pick<A, 'username'|'age'>//只留下usrname和age
type B = Omit<A, 'username'|'age'>//反向挑选

type C = Partial<A>//全部改为可选
type D = Required<A>//全部改为必输

type E = Readonly<A>//全部设置为readonly
type F = Record<keyof A, string> //全部改为string类型

type G = Exclude<string | number | boolean, string> //排除掉string
type H = Extract<string | number | boolean, string> //只留string

class与类型

type与class

ts
class Foo {username: string = 'xiaoming';}
//等价,赋予默认值
class Eoo{
    username: string;
    constructor(){
      this.username = 'xiaoming';
    }
}
let a:Foo = new Foo() //Foo { username: 'xiaoming' }
let b:Eoo = new Eoo() //Eoo { username: 'xiaoming' }

interface与class

ts
interface A {
  username: string
  age: number
  showName(n: string): string
}

class Foo implements A {
  gender: string = 'male'// 可以新增字段,兼容类型
  username: string = 'xiaoming'
  age: number = 20
  showName = (n: string): string => {
    return n
  }
}

泛型与class

ts
class Foo<T> {
  username: T;
  constructor(username: T){
    this.username = username;
  }
}
new Foo<string>('xiaoming');
new Foo<string>(123);//报错

泛型继承

ts
class Foo<T> {
    username: T;
    constructor(username: T){
        this.username = username;
    }
}

class Bar extends Foo<string> {

}
new Bar('abc')
new Bar(12)//报错