首页
统计
Search
1
TypeScript学习笔记
5 阅读
2
《被讨厌的勇气》读后感
5 阅读
3
从零开始的Vue学习
3 阅读
4
摘抄
3 阅读
5
【极客时间】玩转Git三剑客笔记
3 阅读
年度总结
学习笔记
读后感
动漫汇总
日常记录
登录
Search
标签搜索
大数据
git
加密
Vue
CTF
TypeScript
React
Augenstern
累计撰写
10
篇文章
累计收到
0
条评论
首页
栏目
年度总结
学习笔记
读后感
动漫汇总
日常记录
页面
统计
搜索到
1
篇与
TypeScript
的结果
2025-10-17
TypeScript学习笔记
TypeScript入门笔记教程地址:官方文档:TypeScript 菜鸟教程:TypeScript入门教程简单介绍1、TypeScript由微软公司开发,是一种开源的编程语言2、TypeScript是JavaScript的超集,拓展了JavaScript的语法,因此,TS也是兼容JS代码的,只会对TS代码进行编译安装有两种主要的方式来获取TypeScript工具:通过npm(Node.js包管理器)安装Visual Studio的TypeScript插件这里采用npm的方式进行安装npm install -g typescript查看版本tsc -V 初始化一个项目tsc --init 基础语法数据类型布尔值let isDone: boolean = false;数字let decLiteral: number = 6; //十进制 let hexLiteral: number = 0xf00d; //十六进制 let binaryLiteral: number = 0b1010; //二进制 let octalLiteral: number = 0o744; //八进制字符串let name: string = "bob"; name = "smith";字符串除用"或'表示外,还可以使用模板字符串,可以定义多行文本和内嵌表达式,字符串由反引 号`包围,并且以${ expr }这种形式嵌入表达式let name: string = `Xiaohu`; let age: number = 37; let sentence: string = `Hello, my name is ${name}. I'll be ${age+1} years old next month;` console.log(sentence); //显示结果 Hello, my name is Xiaohu. I'll be 38 years old next month;SymbolSymbol 是 唯一且不可变 的数据类型,通常用作对象属性的键// Symbol 类型注解 const sym1: symbol = Symbol(); const sym2: unique symbol = Symbol("key"); // unique symbol 类型 // 作为对象属性 const obj = { [sym2]: "123" // 使用 unique symbol }; console.log(obj[sym2]); // "123"数组两种定义方式第一种在元素类型后面添加[]let list: number[] = [1, 2, 3];第二种使用数组放心,Array<元素类型>let list: Array<number>元组元组类型允许表示一个已知元素数量和类型的数组,各元素的类型不必相同let x: [string, number]; x = ['hello', 10]; // 正确 x = [10, 'hello']; // 错误当访问一个越界的元素,会使用 联合类型 替代x[3] = 'world'; x[4] = 100; console.log(x[5].toString()); //以上都是可以的, 字符串和数字都属于(string | number)类型,'string' 和 'number' 都有 toString x[6] = true; // Error, 布尔不是(string | number)类型联合类型一个变量是多个数据类型中的某一个,可以使用联合类型, 或 的关系function getArg(param: string | number) { return param.length }交叉类型一个变量是多个数据类型的总和,可以使用交叉类型, 与 的关系interface Person { name: string; age: number; } interface Employee { company: string; employeeId: number; } // BusinessPerson 必须同时拥有 Person 和 Employee 的所有属性 type BusinessPerson = Person & Employee;枚举enum类型是对JavaScript标准数据类型的一个补充,使用枚举类型可以为一组数值赋予友好的名字enum Color {Red,Green,Blue} let c:Color = Color.Green; console.log(c); //显示1默认情况下,从0开始为元素编号,也可以手动的指定成员的数值;枚举类型也可以通过值找到对应名字enum Color {Red=1,Green=2,Blue=4} //Green和Blue 不赋值,则默认从2开始 let colorName:string = Color[4]; console.log(colorName); // 显示BlueAnyAny表示任意类型,但不同在于Object只允许赋值,而不能调用其中的方法,即使对象内部真的有对应的方法let notSure: any = 4; notSure.ifItExists(); // 正常 notSure.toFixed(); // 正常 let prettySure: Object = 4; prettySure.toFixed(); // 报错,提示Object没有对应方法Void表示没有任何类型,比如在函数没有返回值时,返回voidfunction warnUser(): void { console.log("This is my warning message"); }void 只能赋undefined和nulllet unusable: void = undefined;Null 和 UndefinedTypeScript里,undefined和null两者各自有自己的类型分别叫做undefined和null,是所有类型的子类型(默认情况);--strictNullChecks标记,null和undefined只能赋值给void和它们各自Nevernever类型表示的是那些永不存在的值的类型,never类型是任何类型的子类型,也可以赋值给任何类型;然而,没有类型是never的子类型或可以赋值给never类型(除了never本身之外), 即使 any也不可以赋值给never。// 返回never的函数必须存在无法达到的终点 function error(message: string): never { throw new Error(message); } // 推断的返回值类型为never function fail() { return error("Something failed"); } // 返回never的函数必须存在无法达到的终点 function infiniteLoop(): never { while (true) { } }Objectobject表示非原始类型,也就是除number,string,boolean,symbol,null或undefined之外的类型接口TypeScript的核心原则之一是对值所具有的shape进行类型检查。 它有时被称做“鸭式辨型法”或“结构性子类型化”。 在TypeScript里,接口的作用就是为这些类型命名和为你的代码或第三方代码定义契约普通接口interface LabelledValue{ label:string; } function printLabel(labelledObj:LabelledValue){ console.log(labelledObj.label); } let myObj = {size:10,label:"Size 10 Object"}; printLabel(myObj);LabelledValue接口就好比一个名字,用来描述上面例子里的要求。它代表了有一个label属性且类型为string的对象。需要注意的是,我们在这里并不能像在其它语言里一样,说传给printLabel的对象实现了这个接口。我们只会去关注值的外形。 只要传入的对象满足上面提到的必要条件,那么它就是被允许的。还有一点值得提的是,类型检查器不会去检查属性的顺序,只要相应的属性存在并且类型也是对的就可以。可选属性带有可选属性的接口与普通的接口定义差不多,只是在可选属性名字定义的后面加一个?符号,可选属性的好处之一是 可以对可能存在的属性进行预定义 ,好处之二是 可以捕获引用了不存在的属性时的错误interface SquareConfig { color?: string; width?: number; }只读属性一些对象属性只能在对象刚刚创建的时候修改其值,可以在属性名前用readonly来指定只读属性属性用readonly,变量用constinterface Point { readonly x: number; readonly y: number; } }函数类型接口也可以描述函数类型interface SearchFunc{ (source:string,subString:string):boolean; } let mySearch: SearchFunc; mySearch = function(source: string, subString: string) { let result = source.search(subString); if (result == -1) { return false; } else { return true; } } //对于函数类型的类型检查来说,函数的参数名不需要与接口里定义的名字相匹配 mySearch = function(src: string, sub: string): boolean { let result = src.search(sub); if (result == -1) { return false; } else { return true; } }数组类型数组类型具有一个index类型表示索引的类型,还有一个相应的返回值类型表示通过索引得到的元素的类型interface StringArray { [index: number]: string; } let myArray: StringArray; myArray = ["Bob", "Fred"];interface NumberDictionary { [index: string]: number; length: number; // 可以,length是number类型 name: string // 错误,`name`的类型不是索引类型的子类型 }实现接口与Java中的接口一致,TypeScript也能够用它来明确的强制一个类去符合某种契约interface ClockInterface { currentTime: Date; setTime(d: Date); } class Clock implements ClockInterface { currentTime: Date; setTime(d: Date) { this.currentTime = d; } constructor(h: number, m: number) { } }类静态部分与实例部分实例部分 :当你使用 new 创建一个类的实例时,实例上拥有的属性和方法。静态部分 :类本身(构造函数)上拥有的属性和方法。当你用一个接口去约束一个类时(使用 implements 关键字),这个接口 只会检查类的实例部分,而不会检查静态部分 。当你用 构造器签名 (用来描述构造函数类型的一种特殊语法)去定义一个接口并试图定义一个类去实现这个接口时会得到一个错误,因为当一个类实现了一个接口时,只对其实例部分进行类型检查。 constructor存在于类的静态部分,所以不在检查的范围内。interface ClockConstructor { new (hour: number, minute: number); } class Clock implements ClockConstructor { currentTime: Date; constructor(h: number, m: number) { } }因此,我们应该直接操作类的静态部分。 看下面的例子,我们定义了两个接口, ClockConstructor为构造函数所用和ClockInterface为实例方法所用。 为了方便我们定义一个构造函数 createClock,它用传入的类型创建实例。interface ClockConstructor { new (hour: number, minute: number): ClockInterface; } interface ClockInterface { tick(); } function createClock(ctor: ClockConstructor, hour: number, minute: number): ClockInterface { return new ctor(hour, minute); } class DigitalClock implements ClockInterface { constructor(h: number, m: number) { } tick() { console.log("beep beep"); } } class AnalogClock implements ClockInterface { constructor(h: number, m: number) { } tick() { console.log("tick tock"); } } let digital = createClock(DigitalClock, 12, 17); let analog = createClock(AnalogClock, 7, 32);因为createClock的第一个参数是ClockConstructor类型,在createClock(AnalogClock, 7, 32)里,会检查AnalogClock是否符合构造函数签名继承接口接口可以相互继承,也可以继承多个接口,创建出多个接口的合成接口interface Shape { color: string; } interface PenStroke { penWidth: number; } interface Square extends Shape, PenStroke { sideLength: number; } let square = <Square>{}; square.color = "blue"; square.sideLength = 10; square.penWidth = 5.0;接口继承类当接口继承了一个类类型时,它会继承类的成员但不包括其实现。当创建了一个接口继承了一个拥有私有或受保护的成员的类时,这个接口类型只能被这个类或其子类所实现(implement)class Control { private state: any; } interface SelectableControl extends Control { select(): void; } class Button extends Control implements SelectableControl { select() { } } class TextBox extends Control { select() { } } // 错误:“Image”类型缺少“state”属性。 class Image implements SelectableControl { select() { } } class Location { }类与Java中的类很类似,成员有属性、构造方法、方法class Greeter { greeting: string; constructor(message: string) { this.greeting = message; } greet() { return "Hello, " + this.greeting; } } let greeter = new Greeter("world");继承派生类通常被称作子类 ,基类通常被称作 超类class Animal { move(distanceInMeters: number = 0) { console.log(`Animal moved ${distanceInMeters}m.`); } } class Dog extends Animal { bark() { console.log('Woof! Woof!'); } } const dog = new Dog(); dog.bark(); dog.move(10); dog.bark();公共,私有与受保护的修饰符public:默认值,可以自由的访问类中定义的成员private:不能在声明它的类的外部访问;只用两个类中都有相同private成员,且来自同一处声明时,这两个类型才是兼容的,protected成员也一样protected:protected成员在派生类中仍然可以访问其他知识点1、readonly修饰符可以使用readonly关键字将属性设置为只读的。只读属性必须在声明时或构造函数里被初始化2、存取器TypeScript支持通过getters/setters来截取对对象成员的访问3、静态属性创建类的静态成员,这些属性存在于类本身上面而不是类的实例上4、抽象类abstract,抽象类做为其它派生类的基类使用函数普通函数和匿名函数// Named function function add(x, y) { return x + y; } // Anonymous function let myAdd = function(x, y) { return x + y; };this和箭头函数箭头函数能保存函数创建时的 this值,而不是调用时的值let deck = { suits: ["hearts", "spades", "clubs", "diamonds"], cards: Array(52), createCardPicker: function() { // NOTE: the line below is now an arrow function, allowing us to capture 'this' right here return () => { let pickedCard = Math.floor(Math.random() * 52); let pickedSuit = Math.floor(pickedCard / 13); return {suit: this.suits[pickedSuit], card: pickedCard % 13}; } } } let cardPicker = deck.createCardPicker(); let pickedCard = cardPicker(); alert("card: " + pickedCard.card + " of " + pickedCard.suit);泛型使用泛型来创建可重用的组件,一个组件可以支持多种类型的数据Hello World不使用any类型是因为any会导致这个函数可以接收任何类型的arg参数,这样就丢失了一些信息:传入的类型与返回的类型应该是相同的function identity<T>(arg: T): T { return arg; }类型推论 :编译器会根据传入的参数自动地帮助我们确定T的类型let output = identity("myString"); 泛型约束<T extends Lengthwise>:这是泛型约束,表示类型 T 必须满足 Lengthwise 接口的要求interface Lengthwise { length: number; } function loggingIdentity<T extends Lengthwise>(arg: T): T { console.log(arg.length); return arg; }
2025年10月17日
5 阅读
0 评论
0 点赞