TypeScrip
是微软开发的一个开源编程语言,通过在JavaScript
的基础上添加静态类型定义构建而成,TypeScript
通过TypeScript
编译器或Babel
转译为JavaScript代码,可运行在任何浏览器,任何操作系统。
IDE
提示JS
超集,扩展新功能下面来几个例子体验一下
目前 TypeScript
的编译有两种方式。一种是使用 TypeScript
自家的编译器 typescript
编译,一种就是使用 Babel + @babel/preset-typescript
编译(这种后面再说)。
使用TS编译器编译ts文件
typescript
模块textnpm install -g typescript
tsc
命令编译texttsc index.ts
需要说明的是Ts默认的是全剧环境,只要文件使用模块化操作那么就会变成局部属性 如下图所示:
如果有一些编译上的特殊需求可以使用 tsconfig.json
,可以使用 tsc init
命令,也可以自己创建文件
可以看下图先简单了解一下
在 TypeScript
里存在两种声明空间:类型声明空间与变量声明空间。
类型声明空间包含用来当做类型注解的内容。
tsclass Foo{}
type Bus = {}
interface Bar{}
你可以将 Foo
,Bus
,Bar
作为类型注解使用,示例如下:
tslet foo:Foo
let bus:Bus
let bar:Bar
变量声明空间包含可用作变量的内容。
tsclass Foo {}
const someVar = Foo;
const someOtherVar = 123;
两个声明空间是不能进行相互赋值操作的,如下图:
上文中的class Foo
比较特殊,它既能为变量赋值,也能为类型注解。因为 class
既提供了一个类型 Foo
到类型声明空间,又同样提供了一个变量 Foo
到变量声明空间。
就是在声明变量的时候,显式的声明他的类型
tslet message:string = 'hello'
上面的:string
就叫做一个类型注解,它的意思就是告诉程序,变量message是一个字符串类型
类型注解能够把我们上面说的两个空间联系到,如下:
ts// 1. 在类型声明空间声明了一个类型Message
type Message = string;
// 2. 在变量声明空间声明了一个变量message,并通过类型注解声明了变量message是一个Message(string)类型
let message: Message = "hello";
类型注解能够强制变量的类型,如果不进行类型注解,TypeScript
会帮助我们进行类型推断。
TypeScript
能根据一些简单的规则推断(检查)变量的类型。例如:
tslet foo = 123; // foo 是 'number'
let bar = 'hello'; // bar 是 'string'
foo = bar; // Error: 不能将 'string' 赋值给 `number`
Typescript
总共可以把基本类型、对象类型、TS新增类型三大部分
string
、number
、boolean
、null
、undefind
、symbol
、bigint
[]
、{}
、function(){}
any
、never
、void
、unkonwn
、enum
类型之间进行或的操作
tslet a: number | string = 1
a = '1'
类型之间进行与的操作
tstype A = {
username: string
}
type B = {
age: number
}
let a: A & B = {
username: 'coder',
age: 24
}
表示永远不存在的值的类型 (用的很少)
ts// 因为a不可能即使number又是string,a是一个永远不存在的值,ts推断出是never
let a: number & string //never
下面是一个never的应用
tsfunction foo(number: 1 | 2 | 3) {
switch (number) {
case 1:
break;
case 2:
break;
default:
const n:never = number // 检测number是否可以走到这里,看所有值是否都被使用到
}
}
any
表示任意类型,ts
不会进行检测,写法可以理解为和js一样。
可以理解为不知道的类型,any
类型相对应的安全类型
类型断言主要用于当 ts
推断出的类型满足不了我们的需求,与手动指定一个类型。
tslet a: unknown = 123
(a as []).map(() => {})
非空断言也是断言的一种,它会排除掉变量中的 null 和 undefeind。告诉ts我的值不是空的
tslet b: undefined | string = undefined
b!.length // b的类型为undefined 和 string ,非空断言排除了undefined所以能调length属性
断言能逃过 ts
的类型检测(就相当于告诉ts不用管了,我说是什么类型就是什么类型,我说非空就非空),但是上面的代码最终执行时还是会报错。所以用断言的时候要小心,这种做法危险出问题了后果自负。
定义数组类型的两种写法
tslet number: number[] = [1,2,3]
let number: Array<number> = [1,2,3] // 泛型的写法
元组类型允许表示已知元素数量和类型的数字,各元素的类型不必相同。可以看成是数组的特殊形式。
tslet a: [number|string] = [1,'2']
tstype A = {
username: string
age?: number // ? 表示可选
}
let a: A ={
username: 'coder'
}
索引签名的思想是在只知道键和值类型的情况下对结构未知的对象进行类型划分。
索引签名的语法相当简单,看起来与属性的语法相似,但有一点不同。我们只需在方括号内写上键的类型,而不是属性名称:{ [key: KeyType]: ValueType }
。
tstype A = {
[index: string]: any
}
let a: {
username: 'coder'
}
[index: string]: any
是一个索引签名,它告诉TypeScript a 必须是一个以string 类型为键,以 any 类型为值的对象。
如果你不知道你要处理的对象结构,但你知道可能的键和值类型,那么索引签名就是你需要的。
定义一个函数类型
tsfunction foo(n:number):number {
return n
}
foo(1)
ts要求函数的形参和实参必须相同,可以通过可选来控制参数不用一致
tsfunction foo(n:number, n1?:string):number {
return n
}
foo(1)
foo(1, 'hello')
出了上面的写法定义函数类,还可以用表达式
tslet foo: (n: number) => number = function(n) {return n}
表示函数没有任何返回值得到的类型
tslet foo = () => {} // foo的类型是 () => void
函数返回void和undefined的区别
函数重载是指函数约束传入不同的参数,返回不同类型的数据,而且可以清晰的知道传入不同的参数得到不同的结果
typescriptfunction add (num1:number| string, num2:number|string) {
return num1 + num2 // × 运算符“+”不能应用于类型“string | number”和“string | number”
}
typescriptfunction add (num1:string, num2: string) : number
function add (num1:number, num2: number) : number
function add (num1:number, num2: string) : number
function add (num1:string, num2: number) : number
function add (num1:any, num2:any): any {
return num1 + num2
}
add(10, 20) // 执行了第2行函数定义
add(10, '20') // 执行了第3行函数定义
TS
支持我们使用类型别名或接口来定义一个可被调用的类型注解
tstype A = {
(): string
}
上面这个类型别名定义了一个可调用注解,它表示一个返回值为 string 的函数。
可调用注解可以针对函数重载进行类型注解
tstype A = {
(n1:number,n2: number):number,
(n1:string,n2:string): string
}
function add(n1: number, n2: number): number;
function add(n1: string, n2: string): string;
function add(n1: number | string, n2: number | string): number | string {
if (typeof n1 === "string" && typeof n2 === "string") {
return n1 + n2;
}
if (typeof n1 === "number" && typeof n2 === "number") {
return n1 + n2;
}
}
let a: A = add
typescriptenum Direction {
LEFT,
RIGHT,
TOP,
BOTTOM
}
枚举类型默认是有值的
上面的枚举值可以看做
typescriptenum Direction {
LEFT = 0,
RIGHT = 1,
TOP = 2,
BOTTOM = 3
}
当然也可以手动赋其他值
本文作者:叶继伟
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!