总结TypeScript相关知识
目录
- 引入
- 认识
- 特点
- 安装使用
- 变量
- 声明
- 类型推导
- JS 和 TS 共有类型
- number类型
- boolean类型
- string类型
- Array类型
- null和undefined类型
- object类型
- symbol类型
- 对象类型
- 函数类型
- 可选和只读
- type 和 interface
- 索引签名
- 类型断言
- 非空类型断言
- 类型缩小
- 严格赋值检测现象
- TS 新增类型
- 字面量类型
- any类型
- unknown类型
- void类型
- never类型
- tuple类型
- 联合类型
- 交叉类型
- 枚举类型
- 泛型
- 映射类型
- 条件类型
- 类型体操
- 模块-声明-配置
引入
随着近几年前端领域的快速发展,让JavaScript
迅速被普及和受广大开发者的喜爱,借助于JavaScript
本身的强大,也让使用JavaScript
开发的人员越来越多,JavaScript
正在慢慢变好,但是直到今天,JavaScript
在类型检测上依然是毫无进展
类型问题:
-
去实现一个核心类库时,如果没有类型约束,那么需要对别人传入的参数进行各种验证来保证代码的容错率
-
去调用别人的函数,对方没有对函数进行任何的注释,只能去看里面的逻辑来理解这个函数需要传入什么参数, 返回值是什么类型
-
如果可以给
JavaScript
加上很多限制,在开发中就可以很好的避免这样的问题了
为了弥补JavaScript
类型约束上的缺陷,很多公司推出了自己的方案:
2014
年,Facebook
推出了flow
来对JavaScript
进行类型检查- 同年,
Microsoft
微软也推出了TypeScript1.0
版本
TypeScript
使用率:
-
Vue2.x
的时候采用的就是flow
来做类型检查 -
Vue3.x
已经全线转向TypeScript
,98.3%使用TypeScript
进行了重构 -
Angular
在很早期就使用TypeScript
进行了项目重构并且需要使用TypeScript
来进行开发 -
最流行的编辑器
VSCode
也是使用TypeScript
来完成的 -
在
React
中已经使用的ant-design
的UI
库,也大量使用TypeScript
来编写
学习TypeScript
不仅仅可以为我们的代码增加类型约束,而且可以培养前端程序员具备类型思维
认识
TypeScript
在GitHub
和官方上对自己的定义:
-
GitHub
说法:TypeScript is a superset of JavaScript that compiles to clean JavaScript output
-
TypeScript
官网:TypeScript is a typed superset of JavaScript that compiles to plain JavaScript
-
翻译:
TypeScript
是拥有类型的JavaScript
超集,它可以编译成普通、干净、完整的JavaScript
代码
特点
-
始于
JavaScript
,归于JavaScript
-
使用现有的
JavaScript
代码,包括流行的JavaScript
库,并从JavaScript
代码中调用TypeScript
代码 -
TypeScript
可以编译出纯净、 简洁的JavaScript
代码,并且可以运行在任何浏览器上、Node.js
环境中和任何支持ECMAScript3
(或更高版本)的JavaScript
引擎中
-
-
TypeScript
是一个强大的工具,用于构建大型项目-
在语言层面上,不仅仅增加了类型约束,而且包括一些语法的扩展,比如枚举类型(
Enum
)、元组类型(Tuple
)等 -
类型允许
JavaScript
开发者在开发JavaScript
应用程序时使用高效的开发工具和常用操作比如静态检查和代码重构 -
类型是可选的,类型推断让一些类型的注释使你的代码的静态验证有很大的不同。类型让你定义软件组件之间的接口和洞察现有
JavaScript
库的行为
-
-
拥有先进的
JavaScript
-
JavaScript
所拥有的特性,TypeScript
全部都是支持的,并且它紧随ECMAScript
的标准 -
TypeScript
在实现新特性的同时,总是保持和ES
标准的同步甚至是领先 -
并且
TypeScript
最终会被编译成JavaScript
代码,所以并不需要担心它的兼容性问题,在编译时也可以不借助于Babel
这样的工具
-
安装使用
-
TypeScript
的环境安装依赖Node
,先保证电脑上有Node
和NPM
环境 -
npm install typescript -g
:安装 -
tsc --version
:查看版本 -
项目通常使用
webpack
配置本地的TypeScript
编译环境和开启一个本地服务,可以直接运行在浏览器上,这个在webpack
中学习 -
我们练习中就简单使用,先写
ts
文件(最后要写export {}
是用来声明一个模块的,告诉TypeScript
当前文件是一个模块,不是一个全局脚本文件,避免命名冲突) -
然后执行
tsc 文件名
编译成js
代码(编译后的代码要把exports
代码注释),在html
引入js
文件在浏览器查看结果
变量
声明
在TypeScript
中定义变量需要指定标识符的类型
-
声明了类型后
TypeScript
就会进行类型检测,声明的类型可以称之为类型注解(Type Annotation
) -
var/let/const 标识符: 数据类型 = 赋值
类型推导
有时候为了方便并不会在声明每一个变量时都写上对应的数据类型,TypeScript
会在一个变量第一次赋值时,根据后面的赋值内容的类型来推断出变量的类型
- 如果是
const
变量,赋值是一个常量字面量,它会推导为字面量类型。如果是let
,则推导为更宽泛的类型,如number
、string
,赋值为不同类型还是会报错let message = 'hello ts' // string类型 message = 123 // 会报错 不能将类型“number”分配给类型“string”let flag = true // boolean类型const age = 18 // 字面量
JS 和 TS 共有类型
number类型
-
数字类型是我们开发中经常使用的类型,
TypeScript
和JavaScript
一样,不区分整数类型(int
)和浮点型(double
),统一为number
类型 -
ES6
新增了二进制和八进制的表示方法,而TypeScript
也是支持二进制、八进制、十六进制的表示
let num: number = 10
num = 18
num = 18.8
num = 100 // 十进制
num = 0b110 // 二进制
num = 0o555 // 八进制
num = 0xf23 // 十六进制
boolean类型
boolean
类型只有两个取值:true
和false
let flag: boolean = true
flag = false
flag = 20 > 30
string类型
string
类型是字符串类型,可以使用单引号或者双引号表示,也支持ES6
的模板字符串来拼接变量和字符串
let message: string = 'hello'
let n: string = 'ts'
message = `hello ${n}`
Array类型
数组类型的定义有两种方式: 下面都表示数组元素必须是string
Array<string>
string[]
let arr1: string[] = ['abc','cba']
let arr2: Array<string> = ['cba','abc']
arr1.push('ddd')
arr2.push('eee')
arr1.push(123) // 报错:Argument of type 'number' is not assignable to parameter of type 'string'
arr2.push(true) // 报错: Argument of type 'boolean' is not assignable to parameter of type 'string'
null和undefined类型
在 JavaScript
中,undefined
和 null
是两个基本数据类型。 在TypeScript
中,它们各自的类型也是undefined
和null
,也就意味着它们既是实际的值,也是自己的类型
let nu: null = null
nu = {} // Type '{}' is not assignable to type 'null'
let un: undefined = undefined
un = 0 // Type '0' is not assignable to type 'undefined'
object类型
-
object
描述的是所有非原始值的类型(即不包括string
、number
、boolean
、symbol
、null
和undefined
) -
使用
object
类型时,无法直接访问属性,因为TypeScript
并不知道对象的具体结构
let obj: object = { name: "John" };
console.log(obj.name); // 错误:属性 'name' 不存在于 'object' 类型上
obj = { key: "value" }; // 正确
obj = [1, 2, 3]; // 正确
obj = function() {}; // 正确
obj = "string"; // 错误,不能将 'string' 赋值给 'object'
symbol类型
Symbol
是一种基本数据类型,它代表独一无二且不可变的值。它最常用于对象属性的键值,保证每个 Symbol
都是唯一的,防止属性名冲突
let sym1: symbol = Symbol();
let sym2: symbol = Symbol("description");console.log(sym1 === sym2); // false,两个 Symbol 值是唯一的
对象类型
具体学习这篇文章:待后面补充
函数类型
具体学习这篇文章:待后面补充
可选和只读
-
可选:可选属性意味着该属性可以有,也可以没有,属于非必须的属性。如果没有赋值,这个属性的值为
undefined
,在属性的后面添加一个?
表示let bar: {name: string, age: number} = {name: 'obj',age: 18, }function getInfo(data: {name: string, age: number, height?: number}) {console.log(data) } getInfo(bar) // 如果height不是可选的就会报错说bar缺少属性
-
只读:只读属性意味着该属性一旦赋值之后就无法修改。通常用于防止对象的某些属性在对象初始化后被改变,在属性的前面加
readonly
表示function getInfo(data: {name: string, readonly age: number, height?: number}) {console.log(data.age)data.age = 18 // 会报错 }
-
可选可以结合只读
type Person = {readonly id?: number; // 可选且只读属性name: string; };const person: Person = { name: "Alice" };// 合法,因为 id 是可选的 const personWithId: Person = { id: 1, name: "Bob" };// 错误,因为 id 是只读属性,不能修改 // personWithId.id = 2; // Error: Cannot assign to 'id' because it is a read-only property.
type 和 interface
-
type 新类型名 = 现有类型
:定义类型别名,通过类型别名,可以将复杂的类型定义抽象为一个更简单的名字,并在代码中反复使用;可以用于基础类型、对象类型、联合类型、数组、函数等各种类型type UserType = {name: string;age?: number;readonly height: number };let user: UserType = {name: "Alice",height: 188, };
-
interface
接口:是一种用于定义对象、函数、类等结构的方式interface IUser {name: string;age?: number;readonly height: number }let user: IUser = {name: "Alice",height: 188, };
-
两者区别:
-
区别一:
type
类型使用范围更广,而interface
主要用于定义对象的形状 -
区别二:同名接口可以合并(声明合并),如果两个地方声明了同名的接口,
TypeScript
会将它们的成员自动合并到一个接口中interface ILocal {x: numbery: number }interface ILocal {z: number }const local: ILocal = { // 会合并,必须包含x,y,zx: 100,y: 200,z: 300 }
-
区别三:接口可以继承一个或多个其他接口,使得多个接口可以共享相同的属性和方法定义
interface IAdult {name: string,age: number }interface IWorker {working: () => void }interface ICoder extends IAdult, IWorker {eatting: () => void }const student: ICoder = {name: 'coder',age: 16,working() {console.log('working')},eatting() {console.log('eatting')} }
-
区别四:类可以通过
implements
关键字来实现接口,保证类中定义了接口所要求的所有属性和方法,具体学习这篇文章:待后面补充
-
索引签名
具体学习这篇文章:待后面补充
类型断言
类型断言(Type Assertions
)用于明确地告诉编译器某个值的类型,而不是让编译器自动推断类型,类型断言不会做类型转换,它只是在编译时进行静态检查,帮助你绕过编译器的类型检查限制
- 语法:
-
尖括号语法:
let someValue: any = "this is a string"; let strLength: number = (<string>someValue).length;
-
as
语法: 在使用JSX
的时候,不能使用尖括号语法,必须使用as
语法let someValue: any = "this is a string"; let strLength: number = (someValue as string).length;
-
- 使用时机:
-
当 TypeScript 无法自动推断类型时: 比如使用第三方库返回的
any
类型数据,或者处理一些复杂的联合类型时,类型断言可以帮你明确告诉TypeScript
某个值的具体类型 -
在联合类型中确定某个具体类型: 在联合类型中,你可以使用类型断言将值断言为更具体的类型
-
DOM 元素类型断言: 在访问
DOM
元素时,TypeScript
可能无法准确推断类型。你可以使用类型断言来告诉TypeScript
你知道元素的确切类型,提示方法更友好const inputElement = document.getElementById('input') as HTMLInputElement; inputElement.value = "Hello, World!";
-
- 限制:
-
类型断言并不会改变数据的实际类型,而是让 TypeScript 编译器“信任”你给出的类型。因此,错误的类型断言可能导致运行时错误
let someValue: any = "hello"; let num: number = someValue as number; // 这不会在编译时报错,但会导致运行时错误
-
类型断言不能断言为不相关的类型,例如你不能将一个
string
类型断言为number
类型let someValue: any = "hello"; let num: number = someValue as number; // 无效的断言,编译时不会报错,但运行时可能有问题
-
非空类型断言
允许开发者告诉编译器某个表达式不会为 null
或 undefined
,它通过在表达式后面加上 !
操作符实现
-
使用:
-
基本使用:如果某个
DOM
元素可能为null
,但我们知道在使用时它肯定已经存在,可以使用非空断言const element = document.getElementById("myElement"); console.log(element!.innerHTML); // 使用 `!` 断言告诉 TypeScript 这里 `element` 不会是 `null`
-
函数中的非空断言: 假设你有一个函数返回可能是
null
或undefined
的值,但你确定在某个情况下这个函数一定会返回一个有效值function getValue(): string | undefined {return "Hello"; }const value = getValue(); console.log(value!.toUpperCase()); // 使用 `!` 断言忽略 `undefined` 检查
-
联合类型中的非空断言: 对于联合类型中的
null
或undefined
,你也可以使用非空断言function processValue(value: string | null) {console.log(value!.toUpperCase()); // 告诉编译器 value 绝对不会为 null }processValue("Hello"); // 安全 processValue(null); // 会在运行时抛出错误,因为实际上值为 null
-
-
注意:
-
非空断言不会在运行时进行检查:非空断言只是为了告诉编译器在这个地方忽略
null
或undefined
的检查,但如果你使用非空断言的地方值实际为null
或undefined
,仍然会在运行时抛出错误 -
应谨慎使用:过度使用非空断言可能隐藏代码中的潜在错误。只有在你 非常确定 某个值不会为
null
或undefined
时,才应该使用这个操作符
-
类型缩小
类型缩小通过各种类型守卫来帮助 TypeScript
更精确地推断出变量的类型,从而提高代码的安全性和开发体验。主要缩小方式包括:typeof
、instanceof
、in
、平等缩小(===、!==
)等等
-
typeof
:function printID(id: number | string) {if (typeof id === "string") {console.log(id.length, id.split(" "))} else {console.log(id)} }
-
平等缩小(
===、!==
):type localType = 'up' | 'down' | 'left' | 'right' function getLocal(local: localType) {if(local === 'up') {console.log('向上走')} }
-
instanceof
:function formatDate(date: string | Date) {// if(typeof date === 'string') {// console.log(date)// }else {// console.log(date.getTime())// }if(date instanceof Date) { // 判断date是不是Date的实例console.log(date.getTime())}else {console.log(date)} }
-
in
操作符:interface ISwim {swim: () => void }interface IRun {run: () => void }function move(animal: ISwim | IRun) {if ("swim" in animal) {animal.swim()} else if ("run" in animal) {animal.run()} }
严格赋值检测现象
对于对象的字面量赋值,在TypeScript
中有一个非常有意思的现象我们看下面例子,在例子中发现换一种赋值的方式多余的属性不会报错
type TTest = {name: string, age: number, height: number}
const tt ={name: 'tt',age: 28,height: '188',
}
const test1: TTest = tt // 会报错没问题interface ITest {name: string,eatting: () => void
}
const it = {name: 'it',age: 18,eatting: function(){}
}
// 方式一
const test2: ITest = {name: 'it',age: 18, // 多的会报错eatting: function(){}
}
// 方式二
const test3: ITest = it // 多了age属性不会报错
上面现象解释引入TypeScript
成员在GitHub
的issue
中的回答:
翻译理解一下:
-
每个对象字面量最初都被认为是 " 新鲜的(
fresh
)" -
当一个新的对象字面量分配给一个变量或传递给一个非空目标类型的参数时,对象字面量指定目标类型中不存在的属性是错误的
-
当类型断言或对象字面量的类型扩大时,新鲜度会消失
TS 新增类型
字面量类型
它允许将变量的类型限定为特定的值,字面量类型可以是字符串、数字、布尔值、null
、undefined
、bigint
、symbol
等,通过字面量类型,你可以让变量的值更加精确
-
使用:
-
单独使用,使用
const
定义变量时,类型推测就为字面量类型const abc = 'abc' // 这时abc就是为‘abc’的字面量类型 const data = { // 这时data就是为对象的字面量类型url: 'http://localhost:8080',method: 'post' }
-
字符串字面量类型结合联合类型
let direction: "left" | "right" | "up" | "down";direction = "left"; // 正确 direction = "right"; // 正确 direction = "forward"; // 错误,"forward" 不在定义的字面量类型之中
-
数字字面量类型结合联合类型
let option: 1 | 2 | 3;option = 1; // 正确 option = 4; // 错误,因为 4 不在数字字面量类型的范围内
-
布尔字面量类型结合联合类型
let isOpen: true | false;isOpen = true; // 正确 isOpen = false; // 正确
-
-
推理:
/* const data = {url: 'http://localhost:8080',method: 'post' }type methodType = 'get' | 'post' function request(url: string, method: methodType) {console.log(method) } request(data.url, data.method) */ /* 上面的 data.method 会报错:Argument of type 'string' is not assignable to parameter of type 'methodType'因为 data.method 推测出的是string类型,不能赋值给字面量类型所以我们要明确写明 data.method 是个字面量类型解决方法:一:类型断言明确告诉它data.method为post字面量类型request(data.url, data.method as ’post‘)二:const data = {url: 'http://localhost:8080',method: 'post'} as const */type methodType = 'get' | 'post' // 方式一 const data1 = {url: 'http://localhost:8080',method: 'post' } function request1(url: string, method: methodType) {console.log(method) } request1(data1.url, data1.method as 'post') // 类型断言data.method为post字面量类型// 方式二 /* as const:是一个断言操作符,它用于将一个对象或数组的所有属性或元素转换为字面量类型相当于变成了常量对象const data2: {readonly url: 'http://localhost:8080',readonly method: 'post'} = {url: 'http://localhost:8080',method: 'post'} */ const data2 = {url: 'http://localhost:8080',method: 'post' } as const function request2(url: string, method: methodType) {console.log(method) } request2(data2.url, data2.method)
-
应用:
-
参数和请求方法限制:字面量类型通常与联合类型一起使用,用于限制函数参数的值只能是特定的字面量
-
状态管理:在状态管理中,字面量类型可以用来确保状态值总是一个指定的值
-
配置项限制:当某个配置项需要限定特定值时,可以使用字面量类型
-
any类型
在某些情况下,确实无法确定一个变量的类型,并且可能它会发生一些变化,这个时候可以使用any
类型
-
可以对
any
类型的变量进行任何的操作,包括获取不存在的属性、方法 -
给一个
any
类型的变量赋值任何的值,比如数字、字符串的值 -
对于某些情况的处理过于繁琐不希望添加规定的类型注解,或者在引入一些第三方库时,缺失了类型注解,这个时候我们可以使用
any
let a: any = '123'
a = 123
a = null
a = undefined
a = truelet aArr: any[] = ['123', 123, true, null]
unknown类型
unknown
是TypeScript
中比较特殊的一种类型,它用于描述类型不确定的变量
- 和
any
类型有点类似,但是unknown
类型的值上做任何事情都是不合法的
let a: any = '123'
a = 123
a = null
a = undefined
a = true
console.log(a.length) // 不会报错let uk: unknown = '123'
uk = 123
uk = null
uk = undefined
uk = true
console.log(uk.length) // 会报错 'uk' is of type 'unknown'if(typeof uk == 'string') { // 只有当类型范围缩小时再操作才不会报错console.log(uk.length)
}
void类型
void
通常用来指定一个函数是没有返回值的,那么它的返回值就是void
类型
-
当基于上下文的类型推导(
Contextual Typing
)推导出返回类型为void
的时候,并不会强制函数一定不能返回内容,可以返回任何类型 -
如果明确写了函数返回值为
void
类型时,函数只可以返回undefined
-
void
变量可以赋值undefined
,但除了函数返回之外,void
通常不被使用
let unused: void = undefined; // 虽然可以赋值 undefined,但除了函数返回之外,void 通常不被使用
function foo1() { // void类型console.log(123)
}
function foo2(): void {console.log(123)return undefined // 只能返回undefined,返回其他值会报错
}
never类型
never
类型表示那些永远不会存在值的类型。这种类型通常出现在以下几种情况下:
-
函数永远不会返回值: 当一个函数永远不会成功执行到结束,它会抛出错误或导致程序退出,这样的函数返回类型是
never
。比如死循环或者抛出异常的函数 -
不可达的代码: 当代码逻辑到达某个永远不可能发生的分支时,可以用
never
来标记这类情况
function throwError(message: string): never {throw new Error(message);
}function infiniteLoop(): never {while (true) {console.log("This will run forever");}
}function checkType(key: string | number | boolean){switch (typeof key) {case 'string':console.log(key.length)break;case 'number':console.log(key)break;// case 'boolean': // 不加此代码就会报错 Type 'boolean' is not assignable to type 'never'// console.log(!key)// break;default:const type: never = key // 那么这么写的意义何在?在扩展工具时,检测出一些没有处理的case,直接报错 Type 'boolean' is not assignable to type 'never'}
}
tuple类型
tuple
是元组类型,很多语言中也有这种数据类型,比如Python、Swift
等
tuple
和数组有什么区别:
-
数组中通常建议存放相同类型的元素,不同类型的元素是不推荐放在数组中(可以放在对象或者元组中)
-
元组中每个元素都有自己特定的类型,根据索引值获取到的值可以确定对应的类型
-
tuple
通常可以作为返回的值,在使用的时候会非常的方便 -
TypeScript
中的元组继承了数组的行为。在JavaScript
中,数组是动态的,元素可以随时增加或删除。为了兼容这一点,TypeScript
允许通过数组方法往元组中动态添加元素 -
TypeScript
的元组会检查方法传入的参数类型是否与元组的元素类型兼容。只要你添加的元素类型符合元组定义中的类型,就不会有类型错误
let tu: [string, number, boolean, null?] = ['123', 123, true]
let tu0 = tu[0] // tu0就是string类型
tu.push(null)
tu.push('123')
tu.push({}) // 会报错因为元组中没有定义对象// 在函数中使用元组类型是最多的(函数的返回值)
function useState(initialState: number): [number, (newValue: number) => void] {let stateValue = initialStatefunction setValue(newValue: number) {stateValue = newValue}return [stateValue, setValue]
}const [count, setCount] = useState(10)
console.log(count)
setCount(100)
联合类型
联合类型是由两个或者多个其他类型组成的类型,使用 |
表示,表示可以是这些类型中的任何一个值,联合类型中的每一个类型被称之为联合成员(union's members
)
-
传入给一个联合类型的值只要保证是联合类型中的某一个类型的值即可
-
使用时需要进行类型缩小,
TypeScript
可以根据缩小的代码结构,推断出更加具体的类型 -
可以和字面量类型结合使用
let union: boolean | string = '123'
union = true
function handleUnion(un: boolean | string){console.log(un.length) // 报错if(typeof un === 'string') { // 类型缩小console.log(un.length)}else {console.log(un)}
}
handleUnion(union)// 结合字面量类型
type localType = 'up' | 'down' | 'left' | 'right'
function getLocal(local: localType) {if(local === 'up') {console.log('向上走')}console.log(local.length)
}
getLocal('down')
getLocal(123) // 会报错
交叉类型
交叉类型使用 &
符号表示需要满足多个类型的条件
let sn: string & number // 这种值肯定是没有的,没有意义// 交叉类型应用
type personType = { name: string, running: () => void }interface IPerson {age: number,jumping: () => void
}const info: personType & IPerson = { // 将多个对象的属性合并name: 'info',age: 38,running:() => {},jumping:() => {}
}function getPerson (person: personType & IPerson) {console.log(person)
}
getPerson(info)
枚举类型
枚举其实就是将一组可能出现的值,一个个列举出来,定义在一个类型中,这个类型就是枚举类型,枚举允许开发者定义一组命名常量,常量可以是数字、字符串类型
-
数字枚举:是最常见的枚举类型,枚举成员的值默认是从
0
开始递增的,具有反向映射的特性,可以通过枚举的值来获取枚举成员的名字enum Direction {Up, // 0Down, // 1Left, // 2Right // 3 }let dir: Direction = Direction.Up; console.log(dir); // 输出: 0enum Direction {Up = 1, // 1Down, // 2Left, // 3Right // 4 }console.log(Direction.Up); // 输出: 1 console.log(Direction[1]); // 输出: "Up" ,反向取值
-
字符串枚举:每个成员必须显式地设置字符串值,并且不会进行自动递增,不具备反向映射特性
enum Direction {Up = "UP",Down = "DOWN",Left = "LEFT",Right = "RIGHT" }let dir: Direction = Direction.Up; console.log(dir); // 输出: "UP"
-
常量枚举:在需要性能优化的场景下,你可以使用
const enum
来声明常量枚举,会在编译时被完全移除,使用枚举成员的地方会被替换成实际的值const enum Direction {Up,Down,Left,Right }let dir: Direction = Direction.Up; console.log(dir); // 输出: 0
-
枚举成员:分为常量成员(constant member)和计算成员(computed member)
-
常量成员是在编译时计算出值的,或者从数字常量初始化的枚举
-
计算成员是在运行时计算其值的
enum FileAccess {None,Read = 1 << 1, // 常量成员Write = 1 << 2, // 常量成员ReadWrite = Read | Write, // 常量成员G = "123".length // 计算成员 }
-
-
枚举本身可以作为一种类型来使用
enum Direction {Up,Down,Left,Right }function move(direction: Direction) {console.log(direction); }move(Direction.Left); // 输出: 2
泛型
具体学习这篇文章:待后面补充
映射类型
具体学习这篇文章:待后面补充
条件类型
具体学习这篇文章:待后面补充
类型体操
具体学习这篇文章:待后面补充
模块-声明-配置
具体学习这篇文章:待后面补充
相关文章:

总结TypeScript相关知识
目录 引入认识特点安装使用变量声明类型推导 JS 和 TS 共有类型number类型boolean类型string类型Array类型null和undefined类型object类型symbol类型对象类型函数类型 可选和只读type 和 interface索引签名类型断言非空类型断言类型缩小严格赋值检测现象TS 新增类型字面量类型a…...

pdf怎么编辑修改内容?详细介绍6款pdf编辑器功能
■ pdf怎么编辑修改内容? PDF(Portable Document Format)作为一种广泛使用的文件格式,具有特点包括兼容性强、易于传输、文件安全性高、跨平台性、可读性强、完整性、可搜索性、安全性、可压缩性。 PDF文件本身是不可以直接进行编…...

【Blender Python】4.获取场景对象的几种方式
概述 有时候我们需要获取场景中已经添加或存在的对象。本节就总结在Blender Python中获取场景中对象的一些方法。 通过名称获取 py.data的objects()方法返回一个对象集合,可以使用键名或者下标形式获取具体的对象。 在默认新建的场景中,存在三个对象…...

鸿蒙harmonyos next flutter通信之EventChannel获取ohos系统时间
建立通道 flutter代码: EventChannel eventChannel EventChannel("com.xmg.eventChannel"); ohos代码: //定义eventChannelprivate eventChannel: EventChannel | null null//定义eventSinkprivate eventSink: EventSink | null null//建…...

Python 代码编写规范
本规范旨在为 Python 项目的代码编写提供一致性指南。它遵循 Python 社区的 PEP 8 标准,并结合了通用的编程最佳实践。 1. 编码风格 1.1 缩进 使用 4 个空格 作为缩进,不要使用制表符(Tab)。 def example():if True:print(&quo…...

k8s中pod的管理
一、资源管理 1.概述 说到k8s中的pod,即荚的意思,就不得不先提到k8s中的资源管理,k8s中可以用以下命令查看我们的资源: kubectl api-resources 比如我们现在需要使用k8s开启一个东西,那么k8s通过apiserver去对比etc…...

JavaScript中引用数据类型的浅拷贝
在JavaScript中,数据类型被分为“基本数据类型”和“引用数据类型”两大类。基本数据类型包括数值型、字符型、逻辑型、未定义型(undefined)、空型(null)和ES6新增的Symbol类型,引用数据类型包括数组、对象和函数。 当我们在程序中执行变量赋值操作的时候…...

自闭症寄宿学校陕西:提供综合发展的教育环境
在陕西这片古老而充满希望的土地上,有一所特殊的学校——星贝育园康复中心,它如同一座灯塔,照亮了无数自闭症儿童及其家庭前行的道路。这所全国规模较大的广泛性发育障碍全托寄宿制儿童康复训练机构,不仅以其专业的康复训练和独特…...

JS模块化工具requirejs详解
文章目录 JS模块化工具requirejs详解一、引言二、RequireJS 简介1、什么是 RequireJS2、RequireJS 的优势 三、RequireJS 的使用1、配置 RequireJS1.1、基础配置 2、定义模块3、加载模块 四、总结 JS模块化工具requirejs详解 一、引言 随着前端技术的快速发展,Jav…...

JavaScript中的异步编程:从回调到Promise
在JavaScript中,异步编程是一项至关重要的技能,它允许我们在不阻塞主线程的情况下执行耗时操作,如网络请求、文件读取或定时任务。随着JavaScript的发展,异步编程的模式也在不断演进,从最初的回调函数,到现…...

windows下DockerDesktop命令行方式指定目录安装
windows下DockerDesktop指定目录安装(重新安装) 因为DcokerDesktop占用内存较大, 并且拉去镜像后占用本地空间较多,所以建议安装时就更改默认安装路径和镜像存储路径 这里,展示了从下载到安装的过程: 首先下载DcokerDesktop;找到Docker Desktop Installer.exe 并重命名为 do…...

排查和解决JVM OOM实战
JVM OOM介绍 Java内存区域布局 下面的分析中都是基于JDK 8开始的。关于JMM不过多介绍每个区域的作用。OOM不单只会发生在堆内存,也可能是因为元空间或直接内存泄漏导致OOM,此时在OOM的详细信息中会有不同体现。 Java OOM的类别 java.lang.OutOfMemory…...

【Swift官方文档】7.Swift集合类型
集合类型 使用数组、集合和字典来组织数据。Swift 提供了三种主要的集合类型:数组、集合和字典,用于存储值的集合。数组是有序的值集合。集合是无序的唯一值集合。字典是无序的键值对集合。 Swift 中的数组、集合和字典始终清晰地指明它们可以存储的值…...

QT调用最新的libusb库
一:下载libusb文件 下载最新的库的下载网站:https://libusb.info/ 下载: 解压后目录如下: 二:库文件添加QT中 根据自己的编译器选择库: ①将头文件中添加libusb.h ②源文件中添加libusb-1.0.lib ③添加…...

白嫖EarMaster Pro 7简体中文破解版下载永久激活
EarMaster Pro 7 简体中文破解版功能介绍 俗话说得好,想要成为音乐家,就必须先拥有音乐家的耳朵,相信很多小伙伴都已经具备了一定的音乐素养,或者是说想要进一步得到提升。那我们就必须练好听耳的能力,并且把这种能力…...

使用JavaScript写一个网页端的四则运算器
目录 style(内联样式表部分) body部分 html script 总的代码 网页演示 style(内联样式表部分) <style>body {font-family: Arial, sans-serif;display: flex;justify-content: center;align-items: center;height: 100vh;background-color: #f0f0f0;}.calculator {…...

Linux find命令详解及实用示例
Linux 系统中的 find 命令是一个功能强大的工具,用于在文件系统中搜索文件并执行相应的操作。无论是系统管理员还是普通用户,掌握 find 命令都能极大地提高工作效率。本文将详细介绍 find 命令的用法,并通过多个示例展示其在实际中的应用。 …...

CSS基础-常见属性(二)
6、CSS三大特性 6.1 层叠性 如果样式发生冲突,则按照优先级进行覆盖。 6.2 继承性 元素自动继承其父元素、祖先元素所设置的某些元素,优先继承较近的元素。 6.3 优先级 6.3.1 简单分级 1、内联样式2、ID选择器3、类选择器/属性选择器4、标签名选择器/…...

Spring Boot 2.4.3 + Java 8 升级为 Java 21 + Spring Boot 3.2.0
简简单单 Online zuozuo: 简简单单 Online zuozuo 简简单单 Online zuozuo 简简单单 Online zuozuo 简简单单 Online zuozuo :本心、输入输出、结果 简简单单 Online zuozuo : 文章目录 Spring Boot 2.4.3 + Java 8 升级为 Java 21 + Spring Boot 3.2.0前言更换 Java 21 SD…...

如何利用免费音频剪辑软件制作出精彩音频
现在有许多免费的音频剪辑软件可供选择,它们为广大用户提供了丰富的功能和便捷的操作体验,让音频编辑变得更加轻松和有趣。接下来,让我们一起走进这些免费音频剪辑软件的世界,探索它们的独特魅力和强大功能。 1.福昕音频剪辑 链…...

安宝特分享 | AR技术重塑工业:数字孪生与沉浸式培训的创新应用
在数字化转型的浪潮中,AR(增强现实)技术与工业的结合正在呈现新的趋势和应用延伸。特别是“数字孪生”概念的崛起,为AR技术在工业中提供了独特而创新的切入点。 本文将探索AR如何与数字孪生、沉浸式体验和实用案例相结合…...

专题十_穷举vs暴搜vs深搜vs回溯vs剪枝_二叉树的深度优先搜索_算法专题详细总结
目录 搜索 vs 深度优先遍历 vs 深度优先搜索 vs 宽度优先遍历 vs 宽度优先搜索 vs 暴搜 1.深度优先遍历 vs 深度优先搜索(dfs) 2.宽度优先遍历 vs 宽度优先搜索(bfs) 2.关系图暴力枚举一遍所有的情况 3.拓展搜索问题全排列 决策树 1. 计算布尔⼆叉树的值(medi…...

基于springboot vue3 在线考试系统设计与实现 源码数据库 文档
博主介绍:专注于Java(springboot ssm springcloud等开发框架) vue .net php phython node.js uniapp小程序 等诸多技术领域和毕业项目实战、企业信息化系统建设,从业十五余年开发设计教学工作☆☆☆ 精彩专栏推荐订阅☆☆☆☆…...

什么是 HTTP 请求中的 options 请求?
在 Chrome 开发者工具中的 Network 面板看到的 HTTP 方法 OPTIONS,其实是 HTTP 协议的一部分,用于客户端和服务器之间进行“预检”或“协商”。OPTIONS 请求的作用是让客户端能够获取关于服务器支持的 HTTP 方法和其他跨域资源共享 (CORS) 相关的信息&am…...

[图形学]smallpt代码详解(1)
一、简介 本文介绍了著名的99行代码实现全局光照的光线跟踪代码smallpt。 包括对smallpt的功能介绍、编译运行介绍,和对代码的详细解释。希望能够帮助读者更进一步的理解光线跟踪。 二、smallpt介绍 1.smallpt是什么 smallpt(small Path Tracing) 是一个全局光照…...

Vite多环境配置与打包:
环境变量必须以VITE开头 1.VITE_BASE_API: 在开发环境中设置为 /dev-api,这是一个本地 mock 地址,通常用于模拟后端接口。 2.VITE_ENABLE_ERUDA: 设置为 "true",表示启用调试工具,通常是为了…...

git维护【.gitignore文件】
在工程下添加 .gitignore 文件【git忽略文件】 *.class .idea *.iml *.jar /*/target/...

【Canvas与色彩】十六等分多彩隔断圆环
【成图】 【代码】 <!DOCTYPE html> <html lang"utf-8"> <meta http-equiv"Content-Type" content"text/html; charsetutf-8"/> <head><title>隔断圆环Draft5十六等分多彩</title><style type"text…...

什么是pip? -- Python 包管理工具
前言 不同的编程语言通常都有自己的包管理工具,这些工具旨在简化项目的依赖管理、构建过程和开发效率,同时促进代码的复用和共享。每个包管理工具都有其独特的特点和优势,开发者可以根据自己的编程语言和项目需求选择合适的包管理工具。 pip是…...

FastAPI框架使用枚举来型来限定参数、FastApi框架隐藏没多大意义的Schemes模型部分内容以及常见的WSGI服务器Gunicorn、uWSGI了解
一、FastAPI框架使用枚举来型来限定参数 FastAPI框架验证时,有时需要通过枚举的方式来限定参数只能为某几个值中的一个,这时就可以使用FastAPI框架的枚举类型Enum了。publish:December 23, 2020 -Wednesday 代码如下: #引入Enum模块 from fa…...