当前位置: 首页 > news >正文

新建网站推广企业网站模板文件管理

新建网站推广,企业网站模板文件管理,网站 f型,网站制作合肥文章目录 一、类型1、定义类型2、any、unknown、never3、基础类型4、联合类型5、交叉类型6、type、typeof7、作用域 二、数据结构1、数组2、元组3、函数类型4、对象类型 三、接口四、泛型五、enum六、断言七、工具1、模块2、namespace3、装饰器4、declare5、运算符6、映射类型7… 文章目录 一、类型1、定义类型2、any、unknown、never3、基础类型4、联合类型5、交叉类型6、type、typeof7、作用域 二、数据结构1、数组2、元组3、函数类型4、对象类型 三、接口四、泛型五、enum六、断言七、工具1、模块2、namespace3、装饰器4、declare5、运算符6、映射类型7、类型工具8、语法注释9、tsconfig.json TypeScript 可以看成是 JavaScript 的超集superset即它继承了后者的全部语法添加了一个独立的类型系统 一、类型 1、定义类型 js的类型是动态的变量定义以后可以赋值另一个类型的值这导致了不确定性 // 报错 // 不能将类型“number”分配给类型“string”。 let bar:string 123;// 类型推断为string; 鼠标放在sayHello函数上查看函数定义可以看到 // 返回值类型被推断; // (local function) sayHello(name: string | number): string function sayHello(name:string | number){return name ; } sayHello(zhangsan)2、any、unknown、never // any类型 // 加了any类型感觉是回到了js当然一般的项目会限制使用any类型 let anyVar: any 123; let anyVarUndefined: any;anyVar hello world; let anyVarbar anyVar; console.log(anyVar); // 输出hello world console.log(anyVarUndefined); //不会报错any类型可以赋值undefined console.log(anyVarbar 123); // any类型变量赋值给其他变量会导致其他变量也变成any类型// 不给变量定义类型那么等于any类型 // (local function) getNumber(count1: any, count2: any): any function getNumber(count1, count2){return count1 count2; }// unknown // 类型感觉只是对值的类型规定而不能再后续正常使用 let num: unknown 1; num num 1; // 报错“num”的类型为“未知”。 // 在判断中限制unknown的类型为具体类型就可以使用了 if(typeof num number){num num 1 }// never类型 let neverVar: never; // 空类型不能在任何地方使用 neverVar neverVar 1; // 报错不能将类型“number”分配给类型“never”。 // 一般用于函数永不返回的情况比如抛出异常 function f(): never {throw new Error(Error);// 注意当你返回值类型为never依旧return语句会报错// 需要使用as 类型推定return undefined as never; } // never 是其他类型子集所以可以赋值给其他类型 // never是底层类型在这之上可以再次定义类型 let v1:number f(); // 不报错 let v2:string f(); // 不报错3、基础类型 // 基础类型 // string\number\boolean\null\undefined\symbol let str:string hello world; let num1:number 123; let bool:boolean true; let nullVar:null null; let undefinedVar:undefined undefined; let symbolVar:symbol Symbol();// 对象类型 const x:object { foo: 123 }; const y:object [1, 2, 3]; const z:object (n:number) n 1;// 包装类型 // 大写String包含两种一个是字面量类型一个是对象类型 // 小写string只有字面量类型 const s1:String hello; // 正确 const s2:String new String(hello); // 正确 const s3:string hello; // 正确 const s4:string new String(hello); // 错误不能将类型“String”分配给类型“string”。// 大写Object除了null和undefined外Object包含其他所有类型 let obj:Object; obj true; obj hi; // 小写object只有引用数据类型 let obj1:object; obj1 [];// 值类型 // ts中任何变量都是有类型的注意很多时候被默认推导了 // let 会给 strValue1 推导类型为 string let strValue1 hello; // const 会给 strValue2 推导类型为 hello (普通类型的值) const strValue2 hello; // const 会给 objValue 推导类型为 object (引用数据的值) const objValue: object { foo: 1 }; // 注意引用数据会被推导 // const objValueNoType: { // foo: number; // } const objValueNoType { foo: 1 };// 主动设置值类型单个值 let numValue1: 1 123; // 不能将类型“123”分配给类型“1”。 let numValue2: 123 123; // 不能将类型“123”分配给类型“1”。 let numValue3: number 123; // 注意 number 类型 包含 123 类型 numValue2 numValue3; // 错误不能将类型“number”分配给类型“123”。 numValue3 numValue2; // 正确4、联合类型 // 联合类型 // 多个类型组合在一起的类型可以是不同类型的值也可以是同一类型的值 // 可以给变量增加类型 null | undefined let unionValue1: string | number | null | undefined 123; let unionValue2: hello | world | number hello; // 联合类型可以被看成是 类型范围的扩大 // 使用的时候需要类型缩小否则会报错也就是说类型范围的变化不会减少工作量 if(typeof unionValue1 number){console.log(unionValue1.toFixed(2)); }5、交叉类型 // 交叉类型 // let intersectionValue1: number | hello // string类型包含hello类型交叉类型就是hello类型 // 最终交叉类型依旧是联合类型number | hello let intersectionValue1: (string | number) (number | boolean | hello) hello;6、type、typeof // type 类型别名 // 给一个类型起一个别名方便使用类型可以是一个变量 // ts增加了类型系统那么需要搭配类型变量更加灵活使用 type MyType string | number | boolean; let myVar: MyType true;// typeof // typeof 在js里返回最终值的类型 // typeof 在ts里获取类型两者是不一样的 console.log(typeof myVar, typeof myVar); // boolean js中的 typeof 运算符 let myTypeofVar1: MyType; // 使用其他变量的类型 // let myTypeofVar2: MyType let myTypeofVar2: typeof myTypeofVar1 true;7、作用域 // 类型变量具有作用域 try {type MyType string | number; } catch (error) {type MyType boolean; }二、数据结构 1、数组 // 数组类型 // 规定了数组中每个元素的类型但不规定元素的个数 // 成员数组类型 // number[] 等价于 (number)[] let arr0: number[] [1, 2, 3]; let arr1: (string | number)[] [1, 2, 3]; // 泛型数组类型 let arr2: Arraystring | number [1, 2, 3];// 获取数组类型其中的一个元素类型 type Names (string | number)[]; type Name Names[0]; // string | number type Name1 typeof arr1[0]; // string | number // 注意类型数据不能打印出来只能在编译期间使用 // console.log(数组类型, Name); // 报错// 数组类型推断 // 自动推断为let arr3: (string | number)[] 前面讲过默认是any类型 let arr3 [1, 2, 3]; // arr3.push(true); // 推断过一次不会继续推断类型不对会报错// 只读数组 // 数组的元素不能被修改只能读取 let readonlyArr1: readonly string[] [hello, world];// readonly string[] 相当于简化版没有push、pop等属性 // 所以readonly string[] 是父类型string[]是他的子类型子类型添加了更多方法 arr3 readonlyArr1; // 错误父类型不能赋值给子类型 readonlyArr1 [hello, world]; // 正确 // 简单说属性多\功能全的类型可以赋值给属性少的类型如果他们有父子关系但是反过来不行// 另外三种只读数组 // ReadonlyArray\Readonly\const const a1:ReadonlyArraynumber [0, 1];const a2:Readonlynumber[] [0, 1];const arr [0, 1] as const;// 多维度数组; // 从左往右读取最左边是数组最深层的元素最右边是数组最外层的元素 const arr4: string[][] [[hello, world], [foo, bar]];2、元组 // 元组类型 // 规定了数组中每个元素的类型且元素的个数也做规定可选元素可以用?表示只能放在最后面 let tuple1: [string, number?] [hello, 123]; // ... 扩展运算符可以增加无限多个元素 let tuple2: [string, ...number[],] [hello]; // 元组中元素的名称, 没有实际意义只是语义化的作用 let tuple3: [message: string, count: number] [hello, 123]; // 获取元组类型的元素类型通过数字索引 type TupleType [string, number?]; // 注意类型变量也只能赋值给类型变量不能当成值变量使用 type TupleType1 TupleType[1]; // number | undefined // const tuple4 TupleType[0]; // 报错// 只读元组 // readonly 关键词或者使用泛型 Readonly[string, number] let readonlyTuple1: readonly [string, number] [hello, 123]; let readonlyTuple2: Readonly[string, number] [hello, 123];// 元组长度length let tupleLength1: [string, number] [hello, 123]; let tupleLength2: [string, number, boolean?] [hello, 123, true]; let tupleLength3: [string, ...number[], ] [hello, 123, ]; // 当元组长度固定length属性为定值使用其他值会报错 // if(tupleLength1.length 3){ // 报错 // console.log(tupleLength1.length, tupleLength1.length); // } // 当元组长度固定几个选项 1、2、3 if(tupleLength2.length 3){console.log(tupleLength2.length, tupleLength2.length); } // 当元组长度不固定可以随意判断长度 if(tupleLength3.length 3){console.log(tupleLength2.length, tupleLength3.length); }// 元组在函数参数中使用 // 注意函数参数一般有固定的元素数量这个时候使用元组确定数量 function tupleSayHello(name:string, age:number):void{console.log(hello ${name}, your age is ${age}); } const tupleArr1: [string, number] [hello, 123]; const tupleArr2 [hello, 123]; // (string | number)[] 会被认为数量无限 tupleSayHello(...tupleArr1); // 正确 // sayHello(...tupleArr2); // 报错 sayHello只接受有限的2个参数const tupleArr3 [hello, 123] as [string, number]; // 推断类型 // 只读的值数组可以用as const来定义成元组类型 const tupleArr4 [hello, 123] as const; tupleSayHello(...tupleArr4)3、函数类型 // 函数类型 // 默认是有返回值类型推断的可以省略除非条件不充足无法推断 type funType (x: number, y: number) void; // 方式1注意不写参数类型会被推断为any类型 const funAdd1 (x: number, y: number, z) x y; // 方式2 const funAdd2: (x: number, y: number) number (x, y) x y;// 参数数量 let funAdd3: (x: number, y: number) number (x, y) x y; funAdd3 (x: number) x 1; // 正确可以少于初始化定义的参数数量 // funAdd3 (x: number, y: number, z: number) x y z; // 错误参数大于定义的数量// keyof 关键字获取函数的类型注意得到的是type名 const funAdd4: funType (x: number, y: number) x y; // 正确 // keyof 关键字获取函数的类型注意得到的是类型 // const funAdd4 (x: number, y: number) x y; // 正确 const funAdd5: typeof funAdd4 (x, y) x y; // 正确// 对象方式定义函数类型 let fooObj: {(x:number): void; } (x) {return x 1; }; // 等同于 interface FooObj {(x:number): void; } let fooObj1: FooObj (x) {return x 1; };// 特殊类型 Function let fooObj2 (cb: Function, x: number) {return cb(x 1); };// 箭头函数; 注意ts中参数区域要用括号包裹起来返回值写在括号后面 const funAdd6 (x: number): number x;// 参数可选; 注意 y的类型是 number | undefined // 可选的的位置只能在最后面追加参数前面的参数想要使用undefined得单独加 // void 返回值表示不能使用 return 返回内容 const funAdd7 (x: number | undefined 0, y?: number): number {// 注意在代码中写的typeof是值的类型判断而不是类型变量if(typeof x number y ! undefined){return x y;}x?.toFixed(2); // 注意?.运算符可以安全的使用undefinedy?.toFixed(2);// 如果不判断就使用x、y会报错// return x y// 注意必须有默认值因为定义了返回值return 0; }; funAdd7(undefined); // 正确 funAdd7(1); // 正确 funAdd7(1, undefined); // 正确 funAdd7(1, 2); // 正确 funAdd7(undefined, 2); // 正确// 函数参数默认值 // 不可以可选时使用默认值y?: number 0 const funAdd8 (x: number 0, y: number 0) x y; // undefined 不会覆盖默认值 funAdd8(undefined); // 0// 参数结构 type FunTypeAdd9 {x: number, y: number} const funAdd9 ({ x, y }: FunTypeAdd9) x y; funAdd9({ x: 1, y: 2 }); // 3// rest参数 // 剩余参数可以接收任意数量的参数会被存入一个数组中 // args 这个名字可以自定义, 但是必须放在最后面 const funAdd10 (type: string, ...args: number[]) {let sum 0;for(let i 0; i args.length; i){sum args[i];}return sum; }; funAdd10(add, 1, 2, 3); // 6// readonly 关键字 // const funAdd11 (x: readonly number[], y: number) x[0]; // funAdd11( [1, 2, 3], 1); // 错误不能修改只读数组// void 关键字 // 一般用于函数没有返回值或者返回值没有意义的情况 const funAdd12 (x: number): void {// 没有return或者return undefined || null// 或者 throw new Error(something wrong);// 当然函数默认返回的就是undefined// return 1; // 错误// return ; // 错误return; // 正确return undefined; // 正确 }; funAdd12(1); // 正确// 函数重载 // 注意不能写const let定义使用function定义 // 同样不能写箭头函数了 // 当你传入两种模式代码层面做好判断即可不同的参数返回不同的数据类型 function funAdd13 (x: number): number; function funAdd13 (x: string): string; function funAdd13 (x: number | string): number | string {// number numberif(typeof x number){return x 1;}// string stringreturn x 1; }; funAdd13(1); // 2 funAdd13(hello); // hello// 构造函数 // 函数默认是不能当成构造函数使用的 // const funAdd13_child new funAdd13(hello); // 报错// type 构造函数, new 关键字 开头 type FunAdd14_new new (x: number) object;type funAdd_type {new (x: number): object; } // funAdd_type 只能和 Class 结合使用 class FunAdd14_class {constructor(public x: number) { this.x x 1;} } const funAdd14: funAdd_type FunAdd14_class; const funAdd14_child new funAdd14(123); // 正确4、对象类型 // 对象类型 // 字面量对象注意可以使用, 或者; // 属性个数固定必须包含所有属性有点类似于元组强制数量 const objValue1: {name: string,age: number,sayHello: () void; // 函数方式 1sayHello2(): void; // 函数方式 2count?: number // 可选属性 } {name: vbj,age: 18,sayHello: () {console.log(hello ${this.name});} }; console.log(objValue1, objValue1); // 删除必选属性不再被允许 // delete objValue1.name; // 错误 // 删除可选属性可以被删除 delete objValue1.count; // 正确// type 定义对象类型 type ObjValue2 {age: number[],name?: string, } // 获取某一个元素的类型注意类型变量不是纯对象不能使用 ObjValue2.name type ObjValue2Name ObjValue2[name]; // string// interface 定义对象类型 interface ObjValue3 {toString(): string;name: string;age?: number; } // 如果属性是构造函数自带的可以省略如 toString // 因为对象默认自带 toString 方法(Object.prototype.toString) const objValue3: ObjValue3 {name: vbj,age: 18, }; // const objValue3Age objValue3.age * 1; // 错误不能使用 undefined 类型 if (objValue3.age) { // 正确; 可选值需要经过判断再使用有点类似函数参数的可选const objValue3Age objValue3.age * 1; // 正确 }// age1、age2这两个是不一样的 // 前面必须定义属性age1age2可以有可以没有只不过他们的值类型相似 type ObjValue4 {age1: number | undefined,age2?: number, }// readonly 关键字 type ObjValue5 {readonly name: string,readonly age: number,readonly points: number[];readonly count: {count1: number,count2: number,} } const objValue4: ObjValue5 {name: vbj,age: 18,points: [1, 2, 3],count: {count1: 100,count2: 200,} }; // 浅层修改属性报错 // objValue4.name hello; // 错误// 深层属性修改; 正确 objValue4.points[0] 100; // 正确 objValue4.count.count1 100; // 正确// 引用数据会突破readonly限制 // 内存数据优先于关键字 const objValue5 {name: vbj,age: 18,points: [1, 2, 3],count: {count1: 100,count2: 200,} }const objValue6:ObjValue5 objValue5 objValue5.name hello; // 正确 console.log(objValue6, objValue6.name); // hello// 属性名索引索引也具有类型 // 注意索引类型只能写一个比如 propName: string只能写一个type ObjValue7 {[propName: number]: number,// [propName: string]: string, // 报错。索引代表的值类型冲突// string索引优先级更高只要他的容错度高就可以[propName: string]: string | number,// [propName: string]: string | number | undefined,// 索引类型和普通类型很容易冲突// name: boolean // 错误[propName: string] 和 boolean 类型冲突 }// 解构赋值 // 注意单独的变量不能使用类型注解只能集体使用因为:号会被识别成变量别名 const { name: vbjName, age, points, count }: {name: string,age: number, } {name: vbj,age: 18, }// 结构类型; 父类型基础子类型比父类性更加严格包含父类型的属性 const objPointA {x: 1,y: 1 };const objPointB:{ x: number } objPointA; // 正确for (const key in Object.keys(objPointB)) {// 报错objPointB的值中可能出现除x以外的属性默认为any// const item objPointB[key];// 所以只能使用objPointB中确定的属性const item objPointB.x; }// 字面量和变量区别 function sayHelloObj({name: string}): void {} const sayHelloObjParam {name: vbj, age: 18}; sayHelloObj(sayHelloObjParam); // 正确结构类型满足即可参数可多不能少 sayHelloObj({name: 123, age: 18}); // 错误age类型不匹配; 字面量会匹配参数数量// 空对象 // 写空对象会认为后续无法添加属性 const emptyObj: {} {}; // 类型被锁定 const emptyObj: {} // emptyObj.name vbj; // 报错const emptyObj2: Object { name: vbj }; emptyObj2.name vbj; // 报错// 初始化对象 // useState后的泛型区域内就是 countObject的类型如果默认空对象要给每个属性写可选类型 // const [countObject, setCountObject] // useState{ count?: number, age?: number }({}); // 方式 1 // 或者给默认值 const defaultCountObject { count: 0, age: 0 }; const [countObject, setCountObject] useState{ count: number, age: number }(defaultCountObject); // 方式 2 const countObjectValue countObject?.count; useEffect(() {setCountObject({ count: 0, age: 18 }); // useState类型 }, []);三、接口 // interface基础用法 interface Person {firstName?: string;lastName?: string; // 可选属性readonly age?: number; // 只读属性[key: string]: any; // 注意每一种key类型只能有一种值类型[key: number]: string; // key number索引 } const persons: Person {firstName: John,lastName: Doe,age: 30, }; // interface的数字索引可以定义数组 const personKeys: Person [firstName, lastName, age];// interface的函数 interface Person2 {// interface 函数重载注意只能写function不能写箭头函数fun(name: string): string;// fun(name: number): number;fun1?: (age: number) number;fun2?: { (name: string): void }; } // 具体的重载只能在具体函数体使用interface重载只是定义 const person2: Person2 {fun: function (name: string): string {return hello ${name};}, };// 独立函数; (type可以更方便完成) interface Person3 {(name: string, age: number): void; } const person3: Person3 function (name: string, age: number): void {console.log(hello ${name}, your age is ${age}); }; // 构造函数 interface Person4 {new (name: string, age: number): void; } class person4Class {name: any;age: any;constructor(name: any, age: any) {this.name name;this.age age;} } // 注意这里的Person4是接口person4Class是类 const person4: Person4 person4Class;// 继承 interface Animal {name: string; } interface AnimalColor {color: string; } // 当type是对象时可以被继承 type AnimalType {type: string; }; // 继承AnimalAnimalColor; 注意属性不能重重复否则报类型不兼容 interface Dog extends Animal, AnimalColor, AnimalType {bark(): void;// color: number; // 属性“color”的类型不兼容。 } // 同名的interface会合并属性 // 当一个interface没有你想要的属性又不想新增可以直接合并 interface Dog {age: number; // 新增属性 }// type 和 interface 的区别 // 相同点 // 1. type都命名为对象的时候基本一致 // 2. 可以定义属性类型// 不同点 // 1. interface 可以继承type 不可以 // 2. interface 可以合并type 不可以 // 3. interface 只能写对象type 可以写任意类型类型更灵活 // 4. type 有联合类型、交叉类型interface 没有 // 5. type 不能重复声明interface 可以重复声明 // 6. interface 中使用 this 关键字type 中不能使用// 个人总结 // 1. interface 用于组件参数列表API接口参数定义函数返回值更多属于业务层面 // 2. type 用于复杂的类型定义更多属于类型层面四、泛型 // 泛型// 当参数和返回值有关系的时候无法明显看出来关系// 即便是指定类型为一致也只是表明他们类型恰好一致而不是恒定一致性const getArrayFirst1 (num: any[]): any {return num[0];};// 写法 1 functionfunction getArrayFirst2T(num: T[]): T {return num[0];}// 写法 2 箭头函数// 注意 T后面有逗号const getArrayFirst3 T,(num: T[]): T {return num[0];};// 前面两种是根据值推到处类型也可以主动设置类型// 写法 3 interfaceinterface GetArrayFirst4 {T(num: T[]): T;}const getArrayFirst5: GetArrayFirst4 (num) {return num[0];};// 泛型可以不写默认根据实参推导getArrayFirst2([1, 2, 3]); // string | number// 也可以指定类型如果复杂的类型尽可能主动传入泛型变量getArrayFirst2string | number([1, 2, 3]);// interface 泛型// interface 可以 动态设置类型interface GetArrayFirst6T {(num: T[]): T;}// 注意 interface有泛型时必须使用不能省略const getArrayFirst7: GetArrayFirst6string | number (num) {return num[0];};getArrayFirst7([1, 2, 3]);// class 泛型// 类也可以使用泛型class MyClassGetNum1T {// static num: T[] []; // 报错静态属性不能使用泛型只能使用实例属性// constructor 相当于函数的参数入口constructor(public num: T[], ...args: any[]) {}getFirst(): T {return this.num[0];}}// T string | number 默认根据实参推导const myClassNum1 new MyClassGetNum1([1, 2, 3]);// class 和构造函数的 关系// class 改造成 函数function MyClassGetNum1FuncU(ClassCore: typeof MyClassGetNum1, num: U[], ...args: any[]): MyClassGetNum1U {return new ClassCoreU(num, ...args);}// 注意 U 如果不传会根据 存在的U推导// 比如参数有U传了参数但函数没有传U会根据参数确定Uconst myClassNum2 MyClassGetNum1Func(MyClassGetNum1, [1, 2, 3]);console.log(myClassNum2, myClassNum2.getFirst());// type 泛型type GetArrayFirst8T (num: T[]) T;const getArrayFirst9: GetArrayFirst8string | number (num) {return num[0];};getArrayFirst9([1, 2, 3]);// 树形结构的 type type 可以使用自己type TreeT {value: T;left?: TreeT;right?: TreeT;};const treeType: Treenumber {value: 1,left: {value: 2},right: {value: 9}};// 泛型默认值function getArrayFirst10T string(num: T[]): T {return num[0];}// 函数没传泛型根据参数推导并且覆盖默认值getArrayFirst10([1, 2, 3]);class MyClassGetNum2T string {constructor(public num: T[]) {}// 可以设置在参数位置add(num: T): void {this.num.push(num);}}const myClassNum3 new MyClassGetNum2([1, 2, 3]);// 推导的泛型会覆盖默认值// console.log(myClassNum3, myClassNum3.add(true)); // 报错// 数组泛型// Array 相当于一个 interfaceconst arrInterface1: Arraynumber [1, 2, 3];// 只读数组 ReadonlyArrayconst arrInterface2: ReadonlyArraynumber [1, 2, 3];// arrInterface2.push(1); // 报错// arrInterface2 []; // 报错// 泛型条件约束// 也就是说和默认类型不同约束类型是不会被覆盖的会和T一起构成联合类型// 简单说 A extends B 就是 A 必须是 B 的子类型;// A 范围小一些B 范围大(条件宽松)// 注意 10 指的是T的默认值不是stringfunction getArrayFirst11T extends number | string 10(num: T[]): T {return num[0];}// 使用了 extends 约束最好是主动传入泛型而不是依赖默认推导getArrayFirst11number | string([1, 2, 3, 4, 5]);// 1、泛型使用会增加复杂度尽量不要滥用超过 3 个重复的类型考虑使用泛型五、enum // enum 枚举类型// 类似于js对象编译后也是对象enum这里的作用是提供 类型 枚举// 枚举值的特点是名称很重要语义化值可以变化程度大enum Color {// 枚举值可以不用从 0 开始可以设置其他值Red,Yellow, // 默认自增 1Green Green,// 注意数字索引中断以后不会默认自增需要手动设置Blue 0// obj {// name: obj// }}const color: Color Color.Red;console.log(color, color);// 同名枚举值会合并// 注意数字索引为0的位置只有一个其他的同名enum要手动设置enum Color {// Pink, // 0但是报错因为已经存在了Pink Pink}// const enum// 编译后会直接替换成 值不会生成对象; 提高了效率// 编译后// const color 0;// 函数和 enum 类型// 当参数使用 enum不能再传值而是只能穿 enum 类型function getColor(color: Color): string {switch (color) {case Color.Red:return 红色;case Color.Yellow:return 黄色;default:return 未知;}}// console.log(getColor, getColor(Green)); // 报错类型不匹配console.log(getColor, getColor(Color.Green)); // 正确// keyof 索引类型// 得到所有 key 的联合类型typeof 是为了获取类型keyof 获取 keytype Color_key keyof typeof Color;// 获取了所有值 key 表示枚举的值type Color_value { [key in Color]: any };// enum 反向映射// 枚举值可以反向映射到枚举名; 注意枚举值相同反向映射得到最后一个// 注意使用[]反向映射也可以获取枚举值获取枚举值尽量使用Color.Blue规范const color_reverse Color[0]; // 0 映射到 Blue 而不是 Red// Color[123] // 123 映射到 undefined// Color[Blue] // Blue 枚举值 0// Color.Blue; // 0console.log(Color_key, color_reverse, );六、断言 // 断言 type Person_As1 {name: string;age: number;count: number; } const person_assert {name: vbj, } // 断言 即便不满足该类型可以认为指定断言这样可以绕过检查可能导致异常 const person_assert_type1: Person_As1 person_assert as Person_As1; // 当你定义数据初始化时可能没有那么多数据可以指定断言以后逐步添加属性 person_assert_type1.age 18; console.log(person_assert_type1, person_assert_type1.count);// 使用断言的场景很有可能你所使用的数据是很模糊的 // 不确定有哪些属性或者暂时没有; 这个时候很容易把父类性赋值给子类型 // 可以看到不满足条件也被定义了 const person_assert_type2: Person_As1 {name: vbj,age: 18,count: 100,num: 100 } as Person_As1// 断言条件 // 只要as右边是目标类型的子类型即可子类型 父类性 额外属性 // 比如 const value: T1 valueDefault as T2; // T2 必须是 T1 的子类型; // valueDefault是T2的子类型 或者 T2是valueDefault的子类型 const person_assert_type3: Person_As1 {name: vbj, } as { name: string, age: number, count: number, num: number }; // 正确// 最终把数字赋值给字符串 // 注意 any unknown 是所有类型的父类性 // const person_assert_type4: string 100 as string; // 错误 as 两边的值类型不匹配 const person_assert_type4: string 100 as unknown as string; // 正确 中转 unknown 类型// as const 关键字 // let const 关键词会导致变量的类型不一致(简单说const会让变量的类型固定) // let string1: string let string1 JavaScript; // const string2: JavaScript const string2 JavaScript;// let string3 string1 as const; // 报错 as const 前面只能出现基本数据字面量不能是变量 // let string3: JavaScript let string3 JavaScript as const;// 对象字面量 as const 关键字 // 会导致对象属性变成只读readonly, 不能再添加属性; // 属性的值也被改成值类型比如name类型不是string而是vbj const person_as_type5 { name: vbj, } as const; // 正确空对象类型 // person_as_type5.age 1 // 错误不能添加属性// 枚举值类型锁定 enum Person_enum1 {name,age age, } let person_enum1 Person_enum1.name; // Person_enum1 let person_enum2 Person_enum1.name as const; // Person_enum1.name// 非空断言 function AsFun1(value: string | null): string {// 断言 value 非空否则会报错; 这个例子中其实就是排除 null// 非空表示这里一定有值return value!.toUpperCase(); }// 断言函数断言逻辑的复用 // 这里断言只要是string类型就抛出异常 // 注意 asserts value is string 只是语义化具体逻辑需要自己设定 function isStringAs(value:unknown):asserts value is string {if (typeof value ! string)throw new Error(Not a string); } function AsFun2(value: string | number | null): string {isStringAs(value); // 调用断言函数// 如果断言函数使用得当那么错误会出现在断言函数不会在这里报错return value.toUpperCase(); } AsFun2(null);七、工具 1、模块 // 模块// type 和 interface 区分// 类型定义文件module_type.d.tsexport interface interfaceName {name: string;}export type typeName {age: number;}export let num 123;// 引入类型定义文件: const.ts// 方式 1; 单个确定为type类型import { type interfaceName, typeName } from ./module_type;// 方式 2; 批量确定为type类型import type { interfaceName, typeName, num } from ./module_type;const numCurrent num; // 报错num是类型而不是值2、namespace // namespace// 命名空间可以将类型定义文件拆分为多个文件方便管理// 命名空间可以导出和引入// 如果未导出外部无法访问// 可以和函数重名重名的时候相当与给函数增加属性function module_namespace1(){}namespace module_namespace1 {export interface interfaceName {name: string;}}// 同名的命名空间会进行合并// 注意只会合并 export 的成员namespace module_namespace1 {export let num 123;let nullVar null;}namespace module_namespace2 {import interfaceName module_namespace1.interfaceName;import num module_namespace1.num;// import nullVar module_namespace1.nullVar; // 报错}3、装饰器 // 装饰器// 装饰器可以替换类中原有的方法、属性等function simpleDecorator() {console.log(hi);}function simpleDecoratorConstructor() {return function(target: any) {console.log(simpleDecoratorConstructor);}}simpleDecorator// simpleDecorator 会附在A身上当A加载就会调用 simpleDecorator// 注意有多个装饰器靠近 A 的装饰器先触发class A {// 注意装饰器后的代码返回一个函数即可// simpleDecoratorConstructor 返回的函数会替换 getTarget 函数体simpleDecoratorConstructor()getTarget(params: any) {console.log(A getTarget);}} // hiconsole.log(simpleDecorator, new A().getTarget(1));4、declare // declare 关键字// 当外部模块的变量没有类型可以使用 declare 关键字声明变量类型// 不能赋值, 只能定义类型// declare let module_declare: string hello; // 报错declare let module_declare: string;module_declare hello; // 正确// declare module NAMEdeclare module antd {export function message(content: string): void;}declare module ant-design/icons {export function message(content: string): void;}// 强制模块export {};// 全局对象扩展// 注意只能扩展属性不能新增顶层对象declare global {interface String {toRaw(): string;}}String.prototype.toRaw ():string {return toRaw;};5、运算符 // 运算符type T5 {name: string;age: number;};// 返回所有的属性名可能找到原型链上type T6 keyof T5; // T6 是联合类型 name | ageconst t6: T6 name; // 正确keyof T5 返回 T5 的属性名类型// 一般需要使用对象属性的时候使用keyof 返回 属性名的联合类型const T7_Obj {name: vbj,age: 18,};const T7_Key: string name;function T7_Func(obj: T5, key: string) {return obj[key as keyof T5];}T7_Func(T7_Obj, T7_Key)// in 运算符 类型中而不是js的in运算符type Type8 {name: string;age: number;};// 类似于复制所有目标对象的属性到一个新对象中type Type9 {[key in keyof Type8]: any;};// 方括号// 获取类型的属性值type Type10 {name: string;age: number;[key:number]: boolean};// 因为是类型括号所以括号中也可以穿入类型类型括号不能变量值// type Type Type10[na me] // 报错type Type10_number Type10[number] // booleantype Type11 Type10[name] // string// 联合类型也会被识别成联合类型type Type12 Type10[name|age] // string | number// extends 三元运算符// 条件判断根据类型判断返回不同类型公式T extends U ? X : Y// T 是 U 的子类型返回 X否则返回 Ytype Type13 string extends string | number? string : number; // string// infer 关键字// infer 关键字可以帮助我们推导类型变量这样可以得到一个主动推导的变量类型elementtype type14Type Type extends Arrayinfer element ? element : string;type type15 type14string[]; // string// is 关键字// is 关键字可以判断一个变量是否是某个类型相当于语义化具体判断需要自行定义function isType10(a:string): a is string {console.log(isType10 Function);return typeof a string;}if(isType10(isType10_result)){console.log(isType10_result);}// 类型中的字符串模板type Type16 hello ${string} world; // hello string world// satisfies 关键字// 手动类型检测, 帮助你进行类型报错提示type Type17 {name: string;age: number;};// 这里并不想指定类型而使用默认推导但是又希望推导的时候能够进行属性校验// 主要是为了获取开发时的提示const Type17_Obj {name: vbj,aeg: 18,count: 100,} satisfies Type17;const Type17_count Type17_Obj.count;6、映射类型 // 映射类型// 映射类型可以帮助我们快速创建类型// 语法{ [K in keyof T]: X }// 其中K 是 T 的属性名X 是任意类型type Type18 {name: string;readonly age: number;};// 注意前面的、-、readonly表示修改关键字增加或去除只读性// 、-、?表示增加或去除可选性type Type19 {// count: number; // 如果映射不能添加新属性// A as B 可以在之前的键名A基础上转换属性名Breadonly[P in keyof Type18 as newkey ${P}]?: Type18[P];};7、类型工具 // 类型工具type Type20 {name: string;age: number;}// 工具类型类似于语法糖// type PartialT { [P in keyof T]?: T[P] | undefined; }type TypeTool1 PartialType20; // 所有属性可选type TypeTool2 RequiredType20; // 所有属性必填type TypeTool3 ReadonlyType20; // 所有属性只读type TypeTool4 PickType20, name | age; // 选择性的属性type TypeTool5 OmitType20, age; // 排除的属性 返回剩下的属性type TypeTool9 Parameters() void; // 参数类型 可以传入函数类型type TypeTool10 ReturnType() string; // 返回值类型 可以传入函数类型type TypeString1 hellotype TypeString2 UppercaseTypeString1 // HELLO 字符串类类型大小写转换// 使用频率较高的类型工具// 快速创建未知数量属性的对象类型type Type21 Recordstring, any; // 索引类型可以指定索引类型8、语法注释 // 语法注释// ts-nocheck 忽略检查const element document.getElementById(123);// JSDoc 声明// JSDoc 注释可以帮助我们生成文档同时也会帮助我们进行类型检查// 注意类型变量放在{}中/*** param {string} name 这里的类型只是说明参数类型不是实际类型; * typedef {(number | string)} NumberLike 相当于创建type别名* typed {NumberLike} 描述类型是什么使用刚才定义的别名* returns {void} 这里的类型只是说明返回值类型不是实际类型;* extends {HTMLElement} 继承自HTMLElement*/function NoteFun(name: number): string {console.log(Hello name);return Hello;}9、tsconfig.json // tsconfig.json //npm install -g typescript // tsc --init 生成tsconfig.json文件 // 打包编译时会读取tsconfig.json配置 {compilerOptions: {outDir: ./dist, // 编译输出目录allowJs: true, // 允许编译js文件target: es5, // 编译js的目标版本jsx: react, // 使用jsx, 规定输出的jsx文件名lib: [dom, es2021], // 编译时需要引入的内置的类型库sourceMap: true, // 生成sourceMap文件strict: true, // 开启严格模式paths: {/*: [src/*] // 路径映射, 类似于webpack的resolve.alias}},include: [./src/**/*] // 需要编译的文件列表 }
http://www.dnsts.com.cn/news/148713.html

相关文章:

  • 程序员个人博客网站公司网络
  • 怎么样让网站宣传自己百度域名收录提交入口
  • 网站怎样做外链湛江做网站设计
  • 临沧永德网站建设电子商务公司网络营销师培训学校
  • 免费网站建设排行榜企业网站设置
  • 福州网站建站青浦专业做网站
  • 广安公司网站建设宜昌网站建设哪个公司好
  • 如何网站建设平台wordpress文件详解
  • 网站打开加速青岛模板网站建设价格
  • 为网站制定推广计划微信开发工具官网
  • 男女做污的事情网站你对网站第一印象
  • 用ps做网站切片网站设计方案公司
  • 建站公司兴田德润好不好新颖的公司名字大全
  • 网站建设中切图的意义中山模板建站软件
  • 环保公司网站模版东莞网络推广营销公司
  • iis 配置网站详解上海app开发技术公司
  • 网站 中国最早做网站的北京市住房和城乡建设网官网
  • 商盈网站建设网上开店货源的选择主要有
  • 民制作网站价格镇江网站设计开发公司电话
  • 创新的手机网站建设程序开发过程的四个步骤
  • 国家建设部标准官方网站企业建设门户网站成本如何
  • org做后缀的网站网站建设服务条款
  • 医院品牌网站建设cnnic可信网站
  • 建设个网站国外大气网站欣赏
  • 网站建设 拖欠尾款六安房产网
  • 万江区网站建设公司科技有限公司一般是做什么的
  • 检测网站是否被做跳转wordpress 文件上传大小
  • 东莞建设通网站怎么做公众号
  • 网站建设要咨询哪些计算机软件网站建设
  • 北京企业网站建设方黄骅市天气预报15天气