这是我参与「第五届青训营 」伴学笔记创作活动的第 3 天
TypeScript
特点
- 静态类型
- 可读性强:基于语法解析TSDoc、ide增强
- 可维护性强:在编译阶段暴露大部分错误,由此在多人合作的大项目里会有更好的稳定性和开发效率
- js的超集
- 包含于兼容所有js特性,支持共存
- 支持渐进式引入与升级
语法
基础数据类型直接加:类型,
有八种内置类型;默认情况下 null 和 undefined 是所有类型的子类型。就是说你可以把 null 和 undefined 赋值给其他类型。但如果在tsconfig.json指定了"strictNullChecks":true ,null 和 undefined 就只能赋值给 void 和它们各自的类型
对象类型加interface控制类型(一般加一个I在前)
let str: string = "jimmy";
let num: number = 24;
let bool: boolean = false;
let u: undefined = undefined;
let n: null = null;
let obj: object = {x: 1};
let big: bigint = 100n;
let sym: symbol = Symbol("me");
interface IBytedancer{
readonly jobId:number;//只读属性,不可在对象初始化外赋值
name:string;
sex:'man'|'woman'|'other';
age:number;
hobby?:string;//可选属性:可以不存在该属性
[key:string]:any;//任意属性:约束所有对象属性都必须是该属性的子类型
}
函数类型
//可以直接在函数上进行类型补充
function add(x: number, y: number): number{
return x + y;
}
const mult:(x: number, y: number)=> number = (x,y) => x * y;
//也可以给函数类型加一个interface声明(入参和返回值)
interface IMult {
(x: number,y: number): number;
}
const mult: IMult = (x,y) => x * y;
数组类型
/* 类型 + 方括号 表示 */
type IArr1 = number[];
/* 泛型表示 */
type IArr2 = Array<string | number | Record<string,number>>;
/* 元组表示:值同种类型是数组,可以不同类型是元组 */
type IArr3 = [number, number,string,string];
/* 接口表示 */
interface IArr4 {
[key: number]: any;
}
const arr1: IArr1 = [1,2,3,4,5,6];
const arr2: IArr2 = [1,2,'3','4',{a: 1}];
const arr3: IArr3 = [1,2,'3','4'];
const arr4: IArr4 = ['string',()=>null,{},[]];
补充类型
type IEmptyFunction = () => void;//空类型,表示无赋值
type IAnyType = any;//任意类型,是所有类型的子类型
enum EnumExample {//枚举类型: 支持枚举值到枚举名的正、反向映射
add ='+'
mult = '*'
}
EnumExample['add'] === '+';
EnumExample['+']=== 'add';
enum ECorlor [ Mon, Tue, Wed, Thu, Fri, Sat, Sun };
ECorlor['Mon'] === 0;
ECorlor[0] ==='Mon';
type INumArr = Array<number>;//泛型
泛型:泛型约束可以用extends或者'='
function getRepeatArr(target) {
return new Array(100).fill(target);
}
type IGetRepeatArr = (target: any) => any[];
/* 不预先指定具体的类型,而在使用的时候再指定类型的一种特性 */
type IGetRepeatArrR = <T>(target: T)=> T[];
/* 泛型接口 & 多泛型 */
interface IX<T,U> {
key: T;val: U;
}
/* 泛型类 */
class IMan<T> {
instance: T;
}
/* 泛型别名 */
type ITypeArr<T> = Array<T>;
类型别名和类型断言
//通过type关键字定义了IObjArr的别名类型
type IObjArr = Array<{
key: string;
[objKey: string]: any;
}>
function keyBy<T extends IObjArr>(objArr: Array<T>) {
/* 未指定类型时,result类型为 {} */
const result = objArr.reduce((res, val, key) => {
res [key] = val;
return res;
},{});
/* 通过as关键字,断言result类型为正确类型 */
return result as Record<string, T>;
}
- 类型推断:TypeScript 会根据上下文环境自动推断出变量的类型,无须我们再写明类型注解,把这种基于赋值表达式推断类型的能力称之为
类型推断。在 TypeScript 中,具有初始化值的变量、有默认值的函数参数、函数返回的类型都可以根据上下文推断出来。 - 非空断言:在上下文中当类型检查器无法断定类型时,一个新的后缀表达式操作符
!可以用于断言操作对象是非 null 和非 undefined 类型,x! 将从 x 值域中排除 null 和 undefined
let mayNullOrUndefinedOrString: null | undefined | string;
mayNullOrUndefinedOrString!.toString(); // ok
mayNullOrUndefinedOrString.toString(); // ts(2531)
- 确定赋值断言:允许在实例属性和变量声明后面放置一个
!号,从而告诉 TypeScript 该属性会被明确地赋值。为了更好地理解它的作用
let x!: number;
initialize();
console.log(2 * x); // Ok 没!是ariable 'x' is used before being assigned.(2454)
function initialize() { x = 10; }
字面量
- 字符串字面量类型:把一个字符串字面量类型作为变量的类型,主要应用场景是把多个字符串拼接成联合类型
- 数字字面量类型和布尔字面量类型:和字符串类似,联合选用
- 将 const 定义为一个不可变更的常量,在缺省类型注解的情况下,TypeScript 推断出它的类型直接由赋值字面量的类型决定
{
const str = 'this is string'; // str: 'this is string'
const num = 1; // num: 1
const bool = true; // bool: true
}
{
let str = 'this is string'; // str: string
let num = 1; // num: number
let bool = true; // bool: boolean
}
联合/交叉类型
- 联合类型 |,或者
- 交叉类型 &,与,叠加
高级类型
- merge合并
Record<string,any>:record是一个高级类型,前一个是key的类型,后一个是value的类型,此处即限定是object类型keyof:索引类型,相当于取值对象中所有key组成的 字符串字面量in:相当于取值 字符串字面量 中的一种可能
interface IMerge [
<T extends Record<string, any>>(sourceObj: Partial<T>, targetObj: T): T;
}
//表示record中的任意一个项,子集
type IPartial<T extends Record<string,any>> = {
P in keyof T]?: T[P];
}
- 返回值类型
extends跟随泛型出现时表示类型推断(在泛型里出现表示泛型约束),其表达可类比三元表达式;如 T === 判断类型 ? 类型A : 类型B- 关键字infer出现在类型推荐中,表示定义类型变量,可以用于指代类型;如该场景下,将函数的返回值类型作为变量,使用新泛型R表示,使用在类型推荐命中的结果中
type IDelayCall = <T extends () => any>(func: T) => ReturnType<T>;
type IReturnType<T extends (...args: any) => any> = T extends (...args: any)=> infer R ? R : any