定义
TypeScript 是一个开源的编程语言,通过在 JavaScript(世界上最常用的语言之一) 的基础上添加静态类型定义构建而成。
Typescript 与 JavaScript 的区别
| Typescript | Javascript |
|---|---|
| 静态语言 | 动态语言 |
| 一种面向对象的编程语言, 需要TypeScript编译器才能转换为JavaScript文件 | 一种脚本语言, 不需要编译器, 可以在浏览器上运行。 |
| 强类型, 支持静态和动态类型 | 弱类型, 没有静态类型选项 |
| 接口,重载等特性 | 不支持接口,同名函数会被最后定的覆盖 |
如何使用
npm install -g typescript # 安装echo hello_world.ts > const gender: string = 'Female'; # 新建ts文件tsc hello_world.ts # 编译成js
语法
基础类型
// 以下可以不写类型声明,ts可以类型推断let handsome: boolean = true;let age: number = 18;let name: string = 'Rain120;let travel_cities: string[] = ['beijing',];// 使用数组泛型let travel_cities2: Array<string> = ['beijing',];let age: [number, string] = [18, '18']; // Tupleenum Gender { // enumFEMALE,MALE,}let value: any; // 不会对他做任何类型检查let value: unknown; // any 类型对应的安全类型,解决any的问题let u: undefined = undefined;let n: null = null;function warnUser(): void {console.log("This is my warning message");}// 字面量类型const a = '123'let b = '123'let b: 123// 返回never的函数必须存在无法达到的终点function error(message: string): never {throw new Error(message);}// 推断的返回值类型为neverfunction fail() {return error("Something failed");}// 返回never的函数必须存在无法达到的终点function infiniteLoop(): never {while (true) {}}
高级类型
// 函数// 函数声明function getFullName(name?: string = 'test'): string { // 返回值可推断return `Rainy ${name}`;}// 函数表达式const getFullName: (name: string) => string = function(name: string): string {return `Rainy ${name}`;}// 接口interface Profile {readonly name: string;age?: string | number;gender: 'MALE' | 'FEMALE';new (...args: any[]) : Profile[propName: string]: any;}// 交叉类型 交叉类型是将多个类型合并为一个类型。 这让我们可以把现有的多种类型叠加到一起成为一种类型, 它包含了所需的所有类型的特性interface Boy {handsome: boolean;}interface Girl {cute: boolean;}type Person = Boy & Girl;const someone: Person = {handsome: true,cute: false};// 联合类型 联合类型具有 或 关系的多个类型组合而成, 只要满足其中一个类型即可。当你不确定某个对象的值是什么类型时就可以使用 联合类型interface Boy {hair: boolean;tall: boolean;}interface Girl {hair: boolean;cute: boolean;}type Person2 = Boy | Girlconst someone3: Person2 = {hair: true,cute: true}
类型断言
// as 用来手动指定一个值的类型(类型断言 或 类型保护)。换句话来说,就是你比编译器更了解这个变量的类型是什么const someValue: any = "this is a string";const strLength: number = (someValue as string).length;const strLength: number = (<string>someValue).length;// ! 非空断言 不包含 null 和 undefined的值const profile: any = {name: 'Rain120',schools: {}}const getProfile(profile: any) {console.log(profile!.name, profile!.age, profile!.schools!)}const curry = (fn: any) => {return fn!();}
进阶
类型保护
// typeof类型保护function padLeft(value: string, padding: string | number) {if (typeof padding === "number") {return Array(padding + 1).join(" ") + value;}if (typeof padding === "string") {return padding + value;}throw new Error(`Expected string or number, got '${padding}'.`);}interface Padder {getPaddingString(): string}// instanceof 类型保护class SpaceRepeatingPadder implements Padder {constructor(private numSpaces: number) { }getPaddingString() {return Array(this.numSpaces + 1).join(" ");}}class StringPadder implements Padder {constructor(private value: string) { }getPaddingString() {return this.value;}}function getRandomPadder() {return Math.random() < 0.5 ?new SpaceRepeatingPadder(4) :new StringPadder(" ");}// 类型为SpaceRepeatingPadder | StringPadderlet padder: Padder = getRandomPadder();if (padder instanceof SpaceRepeatingPadder) {padder; // 类型细化为'SpaceRepeatingPadder'}if (padder instanceof StringPadder) {padder; // 类型细化为'StringPadder'}// 用户自定义的类型保护function isFish(pet: Fish | Bird): pet is Fish {return (<Fish>pet).swim !== undefined;}interface Bird {fly();layEggs();}interface Fish {swim();layEggs();}let pet = {fly() {console.log(11)}}if (isFish(pet)) {pet.swim();}else {pet.fly();}// 泛型interface Lengthwise {length: number;}function loggingIdentity<T extends Lengthwise>(arg: T): T {console.log(arg.length); // Now we know it has a .length property, so no more errorreturn arg;}// 泛型类class GenericNumber<T> {zeroValue: T;add: (x: T, y: T) => T;}let myGenericNumber = new GenericNumber<number>();myGenericNumber.zeroValue = 0;myGenericNumber.add = function(x, y) { return x + y; };// keyofinterface T {a: number;b: string;}type TKeys = keyof T; // "a" | "b"type PropAType = T['a']; // number// 索引签名interface Foo {[keys: string]: string;}// 映射类型// 将接口下的字段全部变为可选的type Partial<T> = {[K in keyof T]?: T[k];};// 条件类型// T extends U ? X : Ytype TypeName<T> = T extends string? "string": T extends number? "number": T extends boolean? "boolean": T extends undefined? "undefined": T extends Function? "function": "object";// infer// 类型系统在获得足够的信息后,就能将infer后跟随的类型参数推导出来type ReturnType<T> = T extends (...args: any[]) => infer R ? R : any;// 工具类型type Required<T> = {[K in keyof T]-?: T[K];};type Readonly<T> = {readonly [K in keyof T]: T[K];};type Exclude<T, U> = T extends U ? never : T;// K extends keyof any 约束K必须为联合类型type Record<K extends keyof any, T> = {[P in K]: T;};// 递归类型type DeepPartial<T> = {[P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];};
