基础预览

ts可以声明一个变量的类型,此后该变量只能为该类型

let a: number;
a = 10;

如果声明和变量同时进行,ts自动对变量进行类型声明

let a = 10;

对函数的参数进行类型限制

function sum(a: number,b: number) {
   
  return a + b;
}

函数返回值类型限制

function sum(a: number,b: number): number {
   
  return a + b;
}

类型介绍

any类型

let a: any;
let b;

上面两种写法都表示该类型为any,任何a,b可以为任何类型

ts中的字面量

let a: 10;

这样写了之后a的值就只能为10不能为其他值,相当于const

这样写可以采用以下用法

let b: "male" | "female";
b = "male";
b = "female";

联合类型

let c: boolean | string;

unknow类型

unknow相当于一个安全的any,unknow类型的值不能赋给别的类型的值

let a: number;
a = 10;
let w: unknown;
w = 10;

a = w;//显示错误

w是不能赋值给a的

object类型

let c: {
   name: string}//对象里面只能有一个name属性
c = {
   name: 'sss'}

let r: {
   name: string, age?: number}//age可有可无
r = {
   name: 'sss'}

let f: {
   name: string, [propName: string]: any}//后面接任意类型的属性

//表示d得是一个函数,函数的两个参数得是number,返回值得是number
let d: (a: number, b: number) => number
d = function(n1: number, n2: number) {
   
  return n1 + n2
}

array类型

let e: string[];
e = ['a','s']

let v: Array<number>//数组类型

tuple类型

let tuple: [string, string]//数组的长度是固定的
tuple = ['a', 's']

enum类型

枚举类型主要就是将多种值全部列举出来

//enum
enum Gender {
   
  Male = 0,
  Female = 1
}
let i: {
   name: string, gender: Gender};

i = {
   
  name: '钱钱钱',
  gender: Gender.Male
}

console.log(i.gender === Gender.Male)

类型的别名

type myType = 1 | 2 | 3
let o: myType;//o只能是123中的一个
o = 3

类型断言

/* 类型断言(Type Assertion): 可以用来手动指定一个值的类型 语法: 方式一: <类型>值 方式二: 值 as 类型 tsx中只能用这种方式 */

/* 需求: 定义一个函数得到一个字符串或者数值数据的长度 */
function getLength(x: number | string) {
   
  if ((<string>x).length) {
   
    return (x as string).length
  } else {
   
    return x.toString().length
  }
}
console.log(getLength('abcd'), getLength(1234))

类型总结

  • number
  • string
  • boolean
  • object
  • array
  • function
  • void(空值)
  • never(没有值)
  • tuple(元组)
  • enum(枚举)
  • unknown

编译选项

编译单个ts文件

tsc app.ts

编译单个ts文件并监视

tsc app.ts -w

编译所有ts文件

需要先在项目中创建,tsconfig.json文件

tsc

官方文档:

https://www.tslang.cn/docs/handbook/tsconfig-json.html

类的基本使用

class Dog {
   
  name: string
  age: number
  constructor(name: string, age: number) {
   
    //this表示当前实例
    //在构造函数里面对属性进行赋值
    this.name = name
    this.age = age
  }
  say() {
   
    console.log(this.name)
  }
}
const dog = new Dog('aaa', 12)

继承

//继承
class Cat extends Dog {
   
  age: number
  constructor(name: string, age: number) {
   
    super(name, age)//在父类中使用constructor必须写super,调用父类的构造函数
    this.age = age
  }
  run() {
   
    super.say()//super相当于调用父类的say方法
  }
  //子类添加了与父类相同的方法,子类的方***覆盖父类的方法
}

const cat = new Cat('sss', 22)

抽象类

//抽象类
abstract class Name {
   //抽象类不能用来创建对象,只能用来继承
  constructor(parameters) {
   
    
  }
  abstract sayHello();//抽象方法,子类必须得抽象方法进行重写
}

多态

//多态
class Animals {
   
  name: string;
  constructor(name: string) {
   
    this.name = name;
  }
  say() {
   
    console.log(this.name)
  }
}

class Dog extends Animals {
   
  constructor(name: string) {
   
    super(name)
  }

  say() {
   
    console.log('111')
    super.say()
  }
}
class Cat extends Animals {
   
  constructor(name: string) {
   
    super(name)
  }
  say() {
   
    console.log('222')
    super.say()
  }
}

const a1: Animals = new Dog('a1')
const a2: Animals = new Cat('a2')
a1.say()//111,a1
a2.say()///222,a2

静态类型

//静态属性以及静态方法
/* 静态属性, 是类对象的属性 非静态属性, 是类的实例对象的属性 */
class Persons {
   
  static age: number = 12
  constructor(age: number) {
   
    // this.age = name;
    Persons.age = age;
  }
  static say() {
   
    console.log('111');
  }
}
Persons.say()

接口

接口相当于一个对象的类型

接口是对象的状态(属性)和行为(方法)的抽象(描述)

类类型接口

//接口
/** * 接口可以定义类的时候去限制类的结构 * 接口中的所有的属性都不能有实际的值 * 接口只定义对象的结构,而不考虑实际值 * 在接口中所有的方法都是抽象方法 */
interface myInter {
   
  name: string
  sayHello():void;
}

//使用接口
class MyClass implements myInter {
   
  name: string
  constructor(name: string) {
   
    this.name = name
  }
  sayHello() {
   
    console.log('111');
  }
}

对象类型接口

interface IPerson {
   
  readonly id: number
  name: string
  age: number
  sex?: string
}

const person1: IPerson = {
   
  id: 1,
  name: 'tom',
  age: 20,
  sex: '男'
}

函数类型接口

interface Fn {
   
  (tarstr: string, num: number): boolean
}

const myFn: Fn = function(tarstr: string, num: number) {
   
  return true;
}

属性的封装

/** * 属性的封装 * public修饰的属性可以在任意位置访问 * private私有属性,私有属性只能在类内部进行访问 * protected受保护的属性,只能在当前类和当前类的子类中使用 * 可以通过在类中添加方法使得私有属性可以被外部访问 */
class Person {
   
  private _name: string
  private _age: number
  constructor(name: string, age: number) {
   
    this._name = name
    this._age = age
  }

  // getName() {//访问
  // return this.name
  // }
  // setName(value: string) {//设置
  // this.name = value
  // }
  // getAge() {
   
  // return this.age
  // }
  // setAge(value: number) {
   
  // if(value >= 0) {
   
  // this.age = value
  // }
  // }


  //以上可进行简写
  get name() {
   
    return this._name
  }

  set age(value: number) {
   
    this._age = value
  }
}

const per = new Person('sad', 22)

// per.setName('dgd')


per.age = 22

函数

ts中函数的写法跟js中一样,只不过加上了参数类型以及函数返回值类型

函数的完整写法

let myAdd2: (x: number, y: number) => number = function(x: number, y: number): number {
   
  return x + y
}

参数

//可选参数与默认参数
function test(a: string = 'a', age?: number): string {
   
  if(age) {
   
    return a + age;
  }else {
   
    return a;
  }
}
//剩余参数
function aaa(name: string, ...arg: string[]): string {
   
  console.log(arg)//['b','b','c']
  return name + arg;
}
aaa('a','b','b','c')

泛型

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

基本泛型

//a属性类型目前无法确定
function fn<T>(a: T): T {
   
  return a
}
//函数调用的时候,明确T的类型
fn(10)
fn<string>('222')//指定泛型

多个泛型

//指定多个泛型
function fn2<t,k>(a: t, b: k) {
   
  return a
}

fn2<number, string>(123, 'asd')

接口泛型

interface test<T> {
   
  name: T,
  age: T
}

类泛型

class ttt<T> {
   
  name: T
  add: (a: T) => T
}
const t = new ttt<string>()

泛型约束

让泛型t直到自己有length属性

interface Inter {
   
  length: number
}

function fn3<t extends Inter>(a: t) {
   
  return a.length
}