IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> TypeScript常用知识(内附泛型约束详解) -> 正文阅读

[JavaScript知识库]TypeScript常用知识(内附泛型约束详解)

1.函数

1.1 函数写法

//函数声明
function sum(x:number,y:number):number{
    return x+y
}

//函数表达式
let sum = (x:number,y:number):number=>{
    return x+y
}

上面函数表达式只是对右侧的匿名函数进行了类型定义,二等号左边的sum是通过赋值操作进行类型推断出来的,如果需要我们手动给sum添加类型,则应该是这样

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

这样的代码显得比较臃肿,我们可以通过接口的方式来定义一个函数需要符合的形状

interface Sum{
    (x:number,y:number):number
}

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

1.2 函数中的可选参数:

function sum(x:number,y?:number):number{
	if(y){
        return x+y
    }
    return x
}
sum(1,2) //输出3
sum(1) 	//输出1

1.3 函数中的默认参数:

function sum(x:number,y:number=10):number{
    return x+y
}
sum(1,2) 			//输出3
sum(1,undefined) 	//输出11

2.类型别名type 和接口interface

2.1 类型别名

类型别名用来给一个类型起个新名字,

type dataType = number
type dataType = number|string|tuple
type dataType = {
    name:string,
    age:number
}
type dataType = (name:string,age:number)=>number   //定义返回值为numberd的函数类型

2.2 字符串字面量类型

字符串字面量类型用来约束取值只能是某几个字符串中的一个

type dataType = 'red'|'blue'

2.3 接口interface

定义参数或方法的数据类型

interface IUser{
    name:string,
    age:number
}
interface ISetUser{
    (name:string,age:number):void    //定义无返回值接口
}

访问接口里面的类型

//访问接口Test里面的类型
interface Test{
    test:'a'|'b'
}
var a:Test['test'] = 'a'
image-20210925222839328

2.4 type和interface之间的不同点

1 类型别名可以用于其它类型 (联合类型、元组类型、基本类型(原始值)),interface不支持

type dataTypeA = {a:number}
type dataTypeB = {b:number}
//union联合类型
type dataType = dataTypeA | dataTypeb
//tuple元祖
type dataType = [dataTypeA,typeDataB]
//原始值
type dataType = number
//typeof返回值
let div = document.createElement('div')
type dataType = typeof div

2 interface 可以多次定义 并被视为合并所有声明成员 type 不支持

interface Test{
    a:number
}
interface Test{
    b:number
}
const test:Test=(x:1,y:2)  //接口Test变成了{a:number,b:number}

3.默认导出方式不同

//interface支持声明同时导出, type必须先声明后倒出
export  interface Config{
    name:string
}
type dataType = {name:string}
export type {dataType}

2.4 type的基操

type dataType = string|{text:string}
type dataType = Test<string,TestTwo>
type dataType<T> = [T,T]
type dataType<T> = (payload:T)=>void
//type继承type
type PartialPointX = {x:number;}
type Point = PartialPointX & {y:number;}   

2.5 type具有全局性

type具有全局属性 ,当一个type.ts文件中如果不导出当前定义好的类型,则默认当前定义好的类型供全局使用,无需导入

//type.ts
type tableDataType = {
    id:number,
    auth:number,
    enable:number,
    gender:number,
    loginTel:number,
    nickname:string,
    violationNum:number,
    [params:string]:any
}
//假使没有导出这个 tableDataType 类型;在其他文件中可以直接使用tableDataType;不需要要导入
//const tableData = ref<Array<tableDataType>>([])

export type {tableDataType}
//导出这个类型之后 需要对这个类型的文件进行导入之后才能使用

虽然具有全局性,但是不建议直接使用;容易与其他type文件混淆重名导致报错;

建议可以在src目录下单独建一个全局的type文件供全局使用

3.keyof 、in的应用

3.1 keyof

keyof与Object.keys略有相似,只是 keyof 是取 interface 的键而且 keyof 取到键后会保存为联合类型。

interface IUserInfo{
    name:string,
    age:string 
}
type keys = keyof IUserInfo
//相当于 type keys = 'name'|'age'

举个栗子:

利用keyof来增强getValue函数的类型功能

function getValue<T , K extends keyof T>(obj:T,key:K) : T[K] {
    return obj[key]
}
const obj1 = {name:'张三',age:'18'}
getValue(obj1,'name')
image-20210926101223056 image-20210926101339523

3.2 in

in用于遍历类型 、取联合类型的值。主要用于数组和对象的构造 不能用于interface

type Person = 'name' | 'age'
type Tname = {
    [key in Person]:string;
}
//相当于 
type Tname = {
	name:string
    age:string
}
image-20210925161210762

3.3 typeof

获取一个变量声明或对象的类型

export var updPosition = (params:UpdPositionParams)=>{
    return http.put('/web/updPosition',params,['qs'])
}

type func = typeof updPosition		//===> type func = (params:UpdPositionParams):object

image-20210926095146938

4.泛型应用(慎入)

4.1 泛型解释

泛型是指在定义函数/接口/ 类 时,不预先 指定 具体 的 类型,而是在使用的时候再指定类型限制的一种特性。

function test<T>(name:T):T{ return name }
test<String>('张三')		
//指定了T的类型为string

test('张三') 				
//不传泛型、编译器会自动识别传入的参数 将参数的类型认为是泛型指定的类型

function test<T>(name:T,age:T):T{
    return name
}
test('张三')
//如果函数有两个以上的参数,调用函数时只传入一个参数,编译器会默认将第一个参数的数据类型 指认 为泛型指定的 类型

4.2 泛型约束

4.2.1 确保属性存在

有时我们可能希望限制每个类型变量接受的类型数量,这就是泛型约束的作用。

interface Test {
    length:number
}
function test<T extends Test>(name:T):T{
    return name
}
test('张三')

test(12345) //err---->类型“number”的参数不能赋给类型“Test”的参数

T extends Test 用于告诉编译器,我们支持已经实现 Test 接口的任何类型。之后,当我们使用不含有 length 属性的对象作为参数调用 test 函数时,TypeScript 会提示相关的错误信息。

4.2.2 检查对象上的键是否存在

通过 keyof 操作符,我们就可以获取指定类型的所有键。之后我们就可以结合前面介绍的 extends 约束,即限制输入的属性名包含在 keyof 返回的联合类型中。

interface Person{
    idCard:number
    name:string
    body:Array<string>
}
type Test1 = keyof Person   //id | name | body
type Test2 = keyof { [key:string]:Person }  //string|number

//栗子
var  person = {
    idCard:11110000,
    name:'张三',
    body:['leg','hand','foot']
}

function getPriority<T,K extends keyof T>(value:T,key:K):T[K]{
    console.log(value[key])
    return value[key]
}

getPriority(person,'body')   //输出["leg", "hand", "foot"]
getPriority(person,'ti')    //提示报错

4.3 泛型条件类型

T extends U ?X:Y 意思是:若 T 能够赋值给 U,那么类型是 X,否则为 Y

declare function f<T extends boolean>(x: T): T extends true ? string : number;
// Type is 'string | number'
let x = f(Math.random() < 0.5);   //let x: string | numbers

type TypeName<T> = T extends string
  ? "string"
  : T extends number
  ? "number"
  : T extends boolean
  ? "boolean"
  : T extends undefined
  ? "undefined"
  : T extends Function
  ? "function"
  : "object";
 
type T0 = TypeName<string>;
//type T0 = "string"

type T1 = TypeName<"a">;
//type T1 = "string"

type T2 = TypeName<true>;
//type T2 = "boolean"

type T3 = TypeName<() => void>;
//type T3 = "function"

type T4 = TypeName<string[]>;
//type T4 = "object"

分布条件类型

被检查类型是裸类型参数的条件类型称为分布条件类型。在实例化期间,分布条件类型会自动分布在联合类型上。例如,具有T extends U ? X : Y

类型参数A | B | C的实例化T被解析为(A extends U ? X : Y) | (B extends U ? X : Y) | (C extends U ? X : Y)

type T5 = TypeName<string | (() => void)>;
type T5 = "string" | "function"

type T6 = TypeName<string | string[] | undefined>;
type T6 = "string" | "undefined" | "object"

type T7 = TypeName<string[] | number[]>;
type T7 = "object"

在分配条件类型的实例化中,对条件类型内的T extends U ? X : Y引用 ,T被解析为联合类型的各个组成部分(T即指在条件类型分布在联合类型上之后的各个组成部分)

type BoxedValue<T> = { value: T };
type BoxedArray<T> = { array: T[] };
type Boxed<T> = T extends any[] ? BoxedArray<T[number]> : BoxedValue<T>;
 
type T1 = Boxed<string>;
type T1 = {
    value: string;
}
type T2 = Boxed<number[]>;
type T2 = {
    array: number[];
}
type T3 = Boxed<string | number[]>;
type T3 = BoxedValue<string> | BoxedArray<number>

条件类型的分布属性可以方便地用于过滤联合类型

type Diff<T, U> = T extends U ? never : T;
type Filter<T, U> = T extends U ? T : never;

type T1 = Diff<"a" | "b" | "c" | "d", "a" | "c" | "f">;
type T1 = "b" | "d"

type T2 = Filter<"a" | "b" | "c" | "d", "a" | "c" | "f">; // "a" | "c"
type T2 = "a" | "c"

type T3 = Diff<string | number | (() => void), Function>; // string | number
type T3 = string | number

type T4 = Filter<string | number | (() => void), Function>; // () => void
type T4 = () => void
 

4.4 泛型工具类

// Partial 作用就是将某个类型里的属性全部变为可选项 
type Partial<T> = {
    [P in keyof T]?:T[P]
}
interface Todo{
    name:string,
    age:string
}
const a:Partial<Todo> = {}

//Required 作用就是将某个类型里的属性全部变为必选 
type Required<T> = {
    [P in keyof T]-?: T[P];
};
type People = {
    name?:string
    age?:number
}
const a:Required<People> = {
    name:'法外狂徒张三',
    age:20
}

//Record 的作用是将 K 中所有的属性的值转化为 T 类型。
type Record<K extends keyof any, T> = {
    [P in K]: T;
};

//Pick 的作用是将某个类型中的子属性挑出来,变成包含这个类型部分属性的子类型。  
type Pick<T, K extends keyof T> = {
    [P in K]: T[P];
};
interface Todo {
    title: string;
    description: string;
    completed: boolean;
  }
 type TodoPreview = Pick<Todo, "title" | "completed">;    
 const todo: TodoPreview = {
    title: "Clean room",
    completed: false
  };

//Omit 是 Pick 和 Exclude 进行组合, 实现忽略对象某些属性功能
type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;
interface Todo {
    title: string;
    description: string;
    completed: boolean;
  }
const a : Omit<Todo,'title'> = {
    description:'描述',
    completed:true
}
==...............................
  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-12-04 13:21:37  更:2021-12-04 13:23:37 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 7:35:25-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码