typescripts学习笔记||学习ts对比js新增的特性
TS中的Interface接口
主要用途对obeject shape进行约束,规定对象中内容帮助你规范代码
interface Person{
//readonly id :number这样设置的是一个已读属性即在zhangsan创建后不可以改变这个属性
name :string;
age:number;
//age.?:number 这样设置的是一个可选属性
}
//张三中属性必须满足PERSON设置的
let zhangsan:Person = {
name:"zhangsan";
age:20;
}
Function 函数
function add(x : number , y: number ,z?:number):number{
if(typeof z === 'number'){
return x+y+z;
}else{
return x + y;
}
}
//也可以通过定义变量的方式定义函数
const add = (x : number , y: number ,z?:number):number=>{
if(typeof z === 'number'){
return x+y+z;
}else{
return x + y;
}
}
//将变量赋值为函数是需要注意一切一致
let add2:(x:number , y:number ,z?:number)=>number = add1
interface Isum{
//interface在这里也可以声明的函数类型
(x:number , y:number , z?:number) :number
}
//即赋值也可以这样子写
let add2:Isum = add
在一个参数后提添加 :类型 如 :number便是为这个参数添加类型限制,这个函数参数的括号之后加上即为返回值添加类型限定,同interface中一样?:即表示一个可选参数
将一个变量赋值为一个函数时候需要完整的写下返回类型,参数类型等
也可以通过一个interface来描述参数和返回值类型,用于对一个函数变量进行类型限定
类型推论,联合类型,类型断言
ts可以复制的过程中应该的类型,其在没有指定类型的时候为我们推论类型
let str = "str"
//现在str便是string类型
str = 123//便会报错
//这样便是一个联合类型
let numberOrstring : number | string
//既可以
numberOrstring=123
//又可以
numberOrstring ="123"
//当其不确定是哪一个是只能访问共有的方法
//类型断言
function getLength(input : string | number):number{
//这样就是将他看成string才可以直接访问length,不可以断言为联合类型中不存在的类型
const str = input as string
if(str.length)
{
return str.length
}else{
const number = input as number;
return number.toString().length
}
}
//type guard
//ts在条件分支中会智能判断自己的类型
function getLength(input : string | number):number{
if(typeof input === 'string')
{
//这里便可以使用他的方法了,因为他已经确定了他是string类型
return str.length
}else{
const number = input as number;
return number.toString().length
}
}
枚举
通常用于定义常量
enum Direction{
Up,
//Up=10
//则后面便会自动递增
Down,
Left,
Right
}
//通过枚举定义上下左右
console.log(Direction.Up)
//0
console.log(Direction[0])
//"Up"
//由上可知枚举也有反向映射
//字符串枚举
enum Direction{
//将一个设为字符串其中每一项都要为字符串
Up = 'UP',
Down = 'DOWN',
Left = 'LEFT',
Right = 'RIGHT'
}
//通过这种方式可以简单的同api获取到的数据据进行比较
const value = "UP"
if(value ===Direction.Up)
{
console.log("go up")
}
泛型
来源:
如果函数如下写的话
function echo(arg)
{
return arg
}
返回的值便会变成了any类型,ts便丧失了限制类型的作用
只能进行如下修改,但是这样写也只能兼顾一种类型
function echo(arg:number):number
{
return arg
}
泛型,便是在定义函数的时候不预先指定类型而是在使用时后再指定类型的
function echo<T>(arg : T):T{
return arg
}
//这样就是泛型
const result = echo('str')
//这样result便是string类型的
//泛型也可以用于多个类型
//例如像下面的代码交换一个tuple里的两个不同类型的项
function swap<T,U>(tuple:[T,U]):[U,T]{
return [tuple[1],tuple[0]]
}
约束泛型
function echo WithArr<T>(agr :T):T{
console.log(arg.length)
return arg
}
//此时这样调用length属性便会报错因为他不确定T中是否有这样一个属性
//如果直接修改为T[]也只能使得数组这样一种类型可以使用这个函数
//其他的拥有length属性的对象依然不行
//所以我们就需要创建一种让包含这个属性的元素都可以使用这个函数的方法
interface IWithLength{
length : number
}
//创建一个接口包含length
//通过extends实现符合这样约束的内容,让传入值满足一定的条件
function echoWithArr<T extends IWithLength>(agr :T):T{
console.log(arg.length)
return arg
}
console.log(echoWithArr("123123"))
console.log(echoWithArr([1,2,3]))
console.log(echoWithArr({length :10,width :10}))
//这样都是可以的
console.log(echoWithArr(123))
//这样便会报错
泛型在其他方面的使用
泛型在类中的使用
class Queue{
private data = [];
push(item){
return this.data.push(item)
}
pop(){
return this.data.shift()
}
}
const queue = new Queue()
//在这里我们可以压入弹出任意类型的数据
queue.push(1)
queue.push("str")
//弹出时他便不会判断我们的类型导致错误发生
//通过泛型实现输入输出类型是一致的
class Queue<T>{
private data = [];
push(item:T){
return this.data.push(item)
}
pop():T{
return this.data.shift()
}
}
接口中也可以配合泛型使用
interface KeyPair<T,U>{
key :T;
value :U
}
let kp1:KeyPair<number , sting > = {key : 1 ,value :"string"}
let kp1:KeyPair<sting , number > = {value :"string" ,key : 1}
let arr : number[] = [1, 2, 3]
//调用array这个内置的接口
let arr2 : Array<number> = [1, 2, 3]
//两者同义
类型别名 type aliase
很多类型很长所以便于写的话创建类型别名
let sum:(x:number , y:number)=>number
const result = sum(1,2)
type PlusType = (x:number , y:number)=>number
//这样就可以直接通过这个Plustype对sum2进行类型限制
let sum2:PlusType
type StrOrNumber = string | number
let result3:StrOrNumber ="123"
//这样他就可以实string或者number
//字面量
const str : "name" = "name"
//不是name便会出错
//常在枚举中使用
type Directions = 'up'|'down'|'left'|'right'
let toWhere:Directions = 'left'
//这样就吧toWhere取值限定在了Directions中
interface IName{
name :string
}
interface IPerson = IName &{
age :number
}
//这样就给person中添加了iname和age属性,类似于extends