typeScript

4 篇文章 1 订阅

目录

基础类型

数组 -- Array

任意值 -- any

枚举类型 -- enum

变量声明

接口

可选属性

定义函数返回值

只读属性

检查额外的属性

函数类型

可索引类型

public、private、protected --- 类的实例成员

static --- 只属于类本身

readonly

参数属性

存取器

abstract --- 抽象类、抽象方法

函数

函数写法

声明函数类型

剩余参数

this...

泛型

泛型函数

函数本身类型

泛型类

泛型约束


基础类型

基础类型 - TypeScript 中文手册

boolean、number、string、Array、Tuple、enum、any

空值(void)、undefined、null、never

数组 -- Array

// 方式一
let arr1: number[] = [1,2,3,4]

// 方式二
let arr2: Array<number> = [1,2,3]

任意值 -- any

给不确定类型的变量指定一个类型

let notSure: any = 4;
notSure = "maybe a string instead";
notSure = false; // okay

枚举类型 -- enum

// 创建enum实例
enum Color {
  Red = 1,
  Green,
  Blue,
}
//通过.key 取value
let num: Color = Color.Red; 
console.log("num: ", num)  //1

//通过value取key,前提是value是数字且不要有重复的值
let colorName: string = Color[2]; 
console.log("colorName: ", colorName) //Green

变量声明

1.对象展开会丢失其方法

class C {
  p = 12;
  m() {
  }
}
let c1 = new C();
let c2 = { ...c1 };
console.log(c2.p); // 12
c2.m(); // error!

接口

TypeScript的核心原则之一就是对值所具有的结构进行类型检查。

可选属性

接口里的属性不全都是必需的,有些是只在某些条件下存在。但是不能定义接口不存在的属性

  • 可以对可能存在的属性进行预定义
  • 可以捕获引用了不存在的属性时的错误
//定义两个参数,且两个参数非必传
interface ArgConfig {
  color?: string;
  width?: number;
}

function test(arg: ArgConfig){
  console.log(arg)
}

test({color: "red", width: 10})
test({color: "red"})
test({width: 10})
test({height: 10})  //error

定义函数返回值

// 冒号后面定义返回值结构
function axios(arg: string): { msg?: string; code: number; data: any }{

  return {code: 200, data: {}, msg: "成功"}
}

let result = axios("/api/getData")

只读属性

  • readonly  --  定义属性从创建之后不能被修改
  • ReadonlyArray  -- 定义数组从创建之后不能被修改
//方式一
interface point{
  readonly x: number,
  readonly y: number,
}

let point1: point = {x: 1.23, y: 2.45}
point1.x = 3 //error

//方式二
let point: ReadonlyArray<number> = [1,2,3]
point.push(4)  //array

readonly与const的区别

如果时属性不可修改,就用readonly

如果是变量不可修改,就用const

检查额外的属性

当参数被检测到有额外的参数被传入时,ts会报错,如下

//定义两个参数,且两个参数非必传
interface ArgConfig {
  color?: string;
  width?: number;
}

function test(arg: ArgConfig){
  console.log(arg)
}

test({height: 10})  //error 未定义height参数

最简便的方法是使用类型断言

test({height: 10} as ArgConfig)  //okey

函数类型

作用:定义参数和返回值类型,对于函数类型的类型检查来说,函数的参数名不需要与接口里定义的名字相匹配,只需要同等位置上的类型对应就可以通过

// 参数 a、b、c ; 返回值是对象 {res: boolean, code: number}
interface func {
  (a: number, b: number, c?: number): {res: boolean, code: number}
}

let test: func; //定义函数类型
test = function(x: number, y: number){
  return {code: 200, res: x>y}
}
console.log(test(3, 1)) //true

可索引类型

描述那些可以通过索引得到的类型,比如a[0] 、b["red"]

可索引类型具有一个索引签名,他描述了索引的类型和相应索引返回值类型

索引签名:有两种,数字和字符串,可同时使用两种类型的索引,但是数字索引的返回值必须是字符串索引返回值的子类型。因为当使用数字去索引时,ts会把数字转为字符串去索引,因此两者需要保持一致

interface Indexes{
  [index: number]: string
}
let test: Indexes;
test = ["aa", "bb"]
test = ["aa", "bb", 0] //error 因为0不是string类型

public、private、protected --- 类的实例成员

  • 默认成员为public
  • private需要特别声明,派生类和外部变量无法访问;
  • protected需要特别声明,派生类可以访问,外部变量无法访问; 如果构造函数被标记为protected(protected constructor()),则不能被实例化,可以被继承
class Animal {
  name: string;
  private age: number;
  protected score: number;
  constructor(theName: string, theAge: number = 10, score: number = 0) {
    this.name = theName;
    this.age = theAge;
    this.score = score
  }
  move(distanceInMeters: number = 0) {
    console.log(`${this.name} moved ${distanceInMeters}m.`);
  }
  getAge() {
    console.log("age: ", this.age)
    return this.age;
  }
}

class Horse extends Animal {
  // 派生类的构造函数必须包含 "super" 调用,执行super()后,才能使用this
  constructor(name: string) {
    super(name);
    console.log("Horse name: ", this.name);
  }
  move(distanceInMeters = 45) {
    super.move(distanceInMeters);
  }
  getScore(){
    console.log("score: ", this.score)
  }
}

let tom = new Horse("Horse");
tom.move();
tom.getAge()
tom.getScore()

// Horse name:  Horse
// Horse moved 45m.
// age:  10
// score:  0

let animal = new Animal("bird") //error! 构造函数被标记为protected,不能被实例化

static --- 只属于类本身

只属于类本身,不属于类的实例

每个实例想要访问这个属性时,需要在前面加上类的名称,这里使用Animal

class Animal {
  static age = 10
  constructor (public name: string) { }

  userInfo(){
    return `名称:${this.name} 年龄:${Animal.age}`
  }
}

let animal = new Animal('ddu');  
console.log(animal.userInfo()) 
// 名称:ddu 年龄:10

readonly

只读属性只能在声明或构造函数里被初始化

class Animal {
  readonly name: string;
  readonly age: number = 10; //声明
  constructor(theName: string) {  //构造函数
    this.name = theName;
  }
}

let dog = new Animal("Dog");
console.log(dog.age)
dog.age = 20 // Error! 只读属性不能设置

参数属性

变量声明与赋值(constructor)二合一,需要声明public、private、protected

class Animal {
  constructor(public name: string) {  //构造函数
  }
}

let dog = new Animal("Dog");
console.log(dog.name) //Dog

存取器

我们可以调用对象随意的设置变量,但这可能会带来麻烦。所以我们可以捕获set操作,做校验。

  • 只带有get,没有set的存取器被推断为readonly
class Account {
  private _password: string = "12345";

  get password(): string {
    console.log("get")
    return this._password;
  }

  set password(newValue: string){
    console.log("set")
    if(newValue.length >= 5){
      this._password = newValue
    }
    else{
      console.log("error passord")
    }
  }
}

let account = new Account()
console.log(account.password)
// get
// 12345
account.password = "789123"
// set

abstract --- 抽象类、抽象方法

// 抽象方法,定义方法但不定义方法体,必须在派生类中实现

函数

函数写法

函数分为有名字得函数和匿名函数,且定义类型时需要定义参数类型和返回值类型

function add(x: number, y: number): number {
    return x + y;
}
//匿名函数
let myAdd = function(x: number, y: number): number { return x + y; };

声明函数类型

可以先声明函数类型再赋值,也可以在声明类型的同时赋值,类似其他基础类型

let a: string = 'more'

//声明类型
let myAdd: (firstValue: number, secondValue: number) => number 
//赋值
myAdd = function(x: number, y: number): number { return x + y; };

剩余参数

函数传参的个数有时可能不确定,此时可以用剩余参数的方法,把参数放到一个变量数组中。剩余参数接受0~多个参数

function stringJoin(firstName: string, ...nameList: Array<string>) {
  return firstName + " " + nameList.join(' ');
}

let names = stringJoin("Bob", "xs", 'mriao'); //Bob xs mriao

this...

泛型

泛型函数

当我们需要函数参数类型和返回值类型一致时,我们可以使用变量T代替类型,这样就可以适用于多个类型 ------- 泛型变量法

//创建T类型
function identity<T>(arg: T): T {
    return arg;
}
let output = identity<string>("myString");//调用

//创建T类型的数组
function identity<T>(arg: T[]): T[] {
  return arg;
}
let output = identity<number>([1,2,3]);

与非泛型函数的区别:前面增加了一个类型声明 <类型变量>

函数本身类型

声明函数类型

function identity<T>(arg: T): T {
  return arg;
}

let myIdentity: <A>(arg: A) => A = identity

泛型接口

//写法一
interface GenericIdentity{
  <A>(arg: A) : A
}
let myIdentity: GenericIdentity = identity

//写法二
interface GenericIdentity<A>{
   (arg: A) : A
}
let myIdentity: GenericIdentity<string> = identity

泛型类

泛型类类名后跟<>,写入泛型

class GenericNumber<T> {
    zeroValue: T;
    add: (x: T, y: T) => T;
}

let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function(x, y) { return x + y; };

泛型约束

有时我们希望传入的类型具有某个特性,并不想接收所有的类型,此时可以使用接口继承去约束

interface length{
  length: number;
}
interface GenericIdentity<A extends length>{
  (arg: A) : A
}

function identity<T>(arg: T): T {
  return arg;
}

let stringIdentity: GenericIdentity<string> = identity
let numberIdentity: GenericIdentity<number> = identity //Erroe, number没有length属性

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值