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)
sum(1)
1.3 函数中的默认参数:
function sum(x:number,y:number=10):number{
return x+y
}
sum(1,2)
sum(1,undefined)
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
2.2 字符串字面量类型
字符串字面量类型用来约束取值只能是某几个字符串中的一个
type dataType = 'red'|'blue'
2.3 接口interface
定义参数或方法的数据类型
interface IUser{
name:string,
age:number
}
interface ISetUser{
(name:string,age:number):void
}
访问接口里面的类型
interface Test{
test:'a'|'b'
}
var a:Test['test'] = 'a'
2.4 type和interface之间的不同点
1 类型别名可以用于其它类型 (联合类型、元组类型、基本类型(原始值)),interface不支持
type dataTypeA = {a:number}
type dataTypeB = {b:number}
type dataType = dataTypeA | dataTypeb
type dataType = [dataTypeA,typeDataB]
type dataType = number
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)
3.默认导出方式不同
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 PartialPointX = {x:number;}
type Point = PartialPointX & {y:number;}
2.5 type具有全局性
type具有全局属性 ,当一个type.ts文件中如果不导出当前定义好的类型,则默认当前定义好的类型供全局使用,无需导入
type tableDataType = {
id:number,
auth:number,
enable:number,
gender:number,
loginTel:number,
nickname:string,
violationNum:number,
[params:string]:any
}
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
举个栗子:
利用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')
3.2 in
in用于遍历类型 、取联合类型的值。主要用于数组和对象的构造 不能用于interface
type Person = 'name' | 'age'
type Tname = {
[key in Person]:string;
}
type Tname = {
name:string
age:string
}
3.3 typeof
获取一个变量声明或对象的类型
export var updPosition = (params:UpdPositionParams)=>{
return http.put('/web/updPosition',params,['qs'])
}
type func = typeof updPosition
4.泛型应用(慎入)
4.1 泛型解释
泛型是指在定义函数/接口/ 类 时,不预先 指定 具体 的 类型,而是在使用的时候再指定类型限制的一种特性。
function test<T>(name:T):T{ return name }
test<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)
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
type Test2 = keyof { [key:string]:Person }
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')
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;
let x = f(Math.random() < 0.5);
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 T1 = TypeName<"a">;
type T2 = TypeName<true>;
type T3 = TypeName<() => void>;
type T4 = TypeName<string[]>;
分布条件类型
被检查类型是裸类型参数的条件类型称为分布条件类型。在实例化期间,分布条件类型会自动分布在联合类型上。例如,具有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">;
type T2 = "a" | "c"
type T3 = Diff<string | number | (() => void), Function>;
type T3 = string | number
type T4 = Filter<string | number | (() => void), Function>;
type T4 = () => void
4.4 泛型工具类
type Partial<T> = {
[P in keyof T]?:T[P]
}
interface Todo{
name:string,
age:string
}
const a:Partial<Todo> = {}
type Required<T> = {
[P in keyof T]-?: T[P];
};
type People = {
name?:string
age?:number
}
const a:Required<People> = {
name:'法外狂徒张三',
age:20
}
type Record<K extends keyof any, T> = {
[P in K]: T;
};
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
};
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
}
==...............................
|