Vuejs学习笔记--typescript笔记
一、搭建ts的环境:
1.1 项目阶段--------通过webpack搭建一个ts 的环境,需要配置npm install ts-loader typescript -D,通过脚手架会自动配置的
1.2 学习阶段--------安装ts-node -> ts-node TypeScript文件 直接运行 -> 编译+跑在node环境中
二、注意事项:
2.1 所有的ts文件在同一个作用域下,所以变量名不能重复,可以在单独的文件中加入export {},将文件变成独立模块
三、变量的定义-javascript类型:
// 1.number类型的使用 let num: number = 123 // 2.boolean类型的使用 let flag: boolean = true // 3.string类型的使用 let message2: string = "Hello World" // 4.array类型的使用 const names1: Array<string> = [] // 不推荐(react jsx中是有冲突 <div></div>) const names2: string[] = [] // 推荐 // 5.object类型的使用--默认推导 const info = { name: "why", age: 18 } // 6.null和undefined类型的使用--不常用 let n1: null = null let n2: undefined = undefined // 7.symbol类型的使用--不常用 const title1 = Symbol("title") const title2 = Symbol('title') const info = { [title1]: "程序员", [title2]: "老师" } // 个人习惯: 默认情况下, 如果可以推导出对应的标识符的类型时, 一般情况下是不加 // 类型注解: type annotation
四、变量的定义-typescript类型:
// 1.any类型 // 在不想给某些JavaScript添加具体的数据类型时(原生的JavaScript代码是一样) let message: any = "Hello World" // 2.unknown类型 // 用于描述类型不确定的变量 function foo() {return "abc"} function bar() {return 123} let flag = true let result: unknown // 最好不要使用any if (flag) {result = foo()} else {result = bar()} // unknown类型只能赋值给any和unknown类型 // any类型可以赋值给任意类型 // 3.void类型 // 通常用来指定一个函数是没有返回值的,那么它的返回值就是void类型 function sum(num1: number, num2: number) { console.log(num1 + num2) } sum(20, 30) // void类型 // 4.never类型 // 表示永远不会发生值的类型比如一个函数:如果一个函数中是一个死循环或者抛出一个异常,那么这个函数会返回东西吗? // 不会,那么写void类型或者其他类型作为返回值类型都不合适,我们就可以使用never类型; function handleMessage(message: string | number | boolean) { switch (typeof message) { case 'string': console.log("string处理方式处理message") break case 'number': console.log("number处理方式处理message") break case 'boolean': console.log("boolean处理方式处理message") break default: const check: never = message } } // 5.tuple类型 // tuple是元组类型, // tuple和数组有什么区别呢? // 首先,数组中通常建议存放相同类型的元素,不同类型的元素是不推荐放在数组中。(可以放在对象或者元组中) // 其次,元组中每个元素都有自己特性的类型,根据索引值获取到的值可以确定对应的类型; const info: [string, number, number] = ["why", 18, 1.88]
五、变量的定义-类型补充
// 1.参数 // 给参数加上类型注解: num1: number, num2: number // 给返回值加上类型注释: (): number // 在开发中,通常情况下可以不写返回值的类型(自动推导) function sum(num1: number, num2: number) { return num1 + num2 } // 2.匿名函数 // item根据上下文的环境推导出来的, 这个时候可以不添加的类型注解 // 上下文中的函数: 可以不添加类型注解 const names = ["abc", "cba", "nba"] names.forEach(function(item) { console.log(item.split("")) }) // 3.对象类型 // Point: x/y -> 对象类型 // {x: number, y: number} 对象类型 function printPoint(point: {x: number, y: number}) { console.log(point.x); console.log(point.y) } printPoint({x: 123, y: 321}) // 4.可选类型 // Point: x/y/z -> 对象类型 // {x: number, y: number, z?: number} function printPoint(point: {x: number, y: number, z?: number}) { console.log(point.x) console.log(point.y) console.log(point.z) } printPoint({x: 123, y: 321}) printPoint({x: 123, y: 321, z: 111}) // 5.联合类型 // number|string 联合类型 function printID(id: number|string|boolean) { // 使用联合类型的值时, 需要特别的小心 // narrow: 缩小 if (typeof id === 'string') { // TypeScript帮助确定id一定是string类型 console.log(id.toUpperCase()) } else { console.log(id) } } printID(123) printID("abc") // 6.可选类型和联合类型的关系 // 让一个参数本身是可选的 // 一个参数一个可选类型的时候, 它其实类似于是这个参数是 类型|undefined 的联合类型 function foo(message?: string) { console.log(message) } foo() // 7.类型别名 // type用于定义类型别名(type alias) type IDType = string | number | boolean type PointType = { x: number y: number z?: number } function printId(id: IDType) {} function printPoint(point: PointType) {}
六、变量的定义-类型补充2
// 1.类型断言 as // 有时候TypeScript无法获取具体的类型信息,这个我们需要使用类型断言(Type Assertions) // TypeScript只允许类型断言转换为 更具体 或者 不太具体 的类型版本,此规则可防止不可能的强制转换 class Person {} class Student extends Person { studying() {} } function sayHello(p: Person) { (p as Student).studying() } const stu = new Student() sayHello(stu) // 2.非空类型断言 ! // 表示可以确定某个标识符是有值的,跳过ts在编译阶段对它的检测; function printMessageLength(message?: string) { console.log(message!.length) } printMessageLength("aaaa") // 3.可选链的使用 操作符:?. // 它是ES11(ES2020)中增加的特性,它的作用是当对象的属性不存在时,会短路,直接返回undefined,如果存在,那么才会继续执行 type Person = { name: string friend?: { name: string age?: number, girlFriend?: { name: string}}} const info: Person = { name: "why", friend: { name: "kobe", girlFriend: { name: "lily"}}} console.log(info.friend?.name) console.log(info.friend?.age) console.log(info.friend?.girlFriend?.name) // 4. !!的作用 // !!操作符:将一个其他类型转换成boolean类型;类似于Boolean(变量)的方式 const message = "Hello World" const flag = !!message console.log(flag) // 5. ??的作用 // ??操作符:空值合并操作符(??)是一个逻辑操作符,当操作符的左侧是 null 或者 undefined 时,返回其右侧操作数,否则返回左侧操作数; let message: string|null = "Hello World" const content = message ?? "你好啊, 李银河" // const content = message ? message: "你好啊, 李银河" console.log(content) // 6.字面量类型 // "Hello World"也是可以作为类型的, 叫做字面量类型 const message: "Hello World" = "Hello World" // 单独使用意义不大,一般是跟联合类型一块使用 type Alignment = 'left' | 'right' | 'center' let align: Alignment = 'left' align = 'right' align = 'center' // align = 'hehehehe' 会报错 // 7.字面量推理 type Method = 'GET' | 'POST' type Request = { url: string, method: Method } function request(url: string, method: Method) {} const options: Request = { url: "https://www.coderwhy.org/abc", method: "POST" } request(options.url, options.method) // request(options.url, options.method as Method) -->不需要定义type Request了 // 8.类型缩小 // 8.1.typeof的类型缩小 type IDType = number | string function printID(id: IDType) { if (typeof id === 'string') { console.log(id.toUpperCase()) } else { console.log(id) } } // 8.2.平等的类型缩小(=== == !== !=/switch) type Direction = "left" | "right" | "top" | "bottom" function printDirection(direction: Direction) { // 1.if判断 // if (direction === 'left') { // console.log(direction) // } else if () // 2.switch判断 // switch (direction) { // case 'left': // console.log(direction) // break; // case ... // } } // 8.3.instanceof function printTime(time: string | Date) { if (time instanceof Date) { console.log(time.toUTCString()) } else { console.log(time) } } class Student { studying() {} } class Teacher { teaching() {} } function work(p: Student | Teacher) { if (p instanceof Student) { p.studying() } else { p.teaching() } } const stu = new Student() work(stu) // 8.4. in type Fish = { swimming: () => void } type Dog = { running: () => void } function walk(animal: Fish | Dog) { if ('swimming' in animal) { animal.swimming() } else { animal.running() } } const fish: Fish = { swimming() { console.log("swimming") } } walk(fish)
七、变量的定义-函数详解
// 1.函数作为参数时, 在参数中如何编写类型 function foo() {} type FooFnType = () => void function bar(fn: FooFnType) { fn() } bar(foo) // 2.定义常量时, 编写函数的类型 type AddFnType = (num1: number, num2: number) => number const add: AddFnType = (a1: number, a2: number) => { return a1 + a2 } // 3.可选类型是必须写在必选类型的后面的 // y -> undefined | number function foo(x: number, y?: number) {} // 4.必传参数 - 有默认值的参数 - 可选参数 function foo(y: number, x: number = 20) { console.log(x, y) } foo(30) // 5.函数的剩余参数 function sum(initalNum: number, ...nums: number[]) { let total = initalNum for (const num of nums) { total += num } return total } console.log(sum(20, 30)) console.log(sum(20, 30, 40)) console.log(sum(20, 30, 40, 50)) // 6.this的默认推导 // this是可以被推导出来 info对象(TypeScript推导出来) const info = { name: "why", eating() { console.log(this.name + " eating") } } info.eating() // 7.this的不明确类型 type ThisType = { name: string }; function eating(this: ThisType, message: string) { console.log(this.name + " eating", message); } const info = { name: "why", eating: eating, }; // 隐式绑定 info.eating("哈哈哈"); // 显示绑定 eating.call({name: "kobe"}, "呵呵呵") eating.apply({name: "james"}, ["嘿嘿嘿"]) //8.函数重载 // 函数的重载: 函数的名称相同, 但是参数不同的几个函数, 就是函数的重载 function add(num1: number, num2: number): number; // 没函数体 function add(num1: string, num2: string): string; // 函数体,写任意逻辑 function add(num1: any, num2: any): any { if (typeof num1 === 'string' && typeof num2 === 'string') { return num1.length + num2.length } return num1 + num2 } const result = add(20, 30) const result2 = add("abc", "cba") console.log(result) console.log(result2) // 在函数的重载中, 实现函数是不能直接被调用的 // add({name: "why"}, {age: 18})

浙公网安备 33010602011771号