一、基本数据类型
1. TS 基本数据类型
1.1 布尔类型
let boolVar:boolean = false
1.2 数值类型
let numVar:number = 110
1.3 字符串类型
let strVar:string = 'Hello World'
1.4 数组类型
第一种
let arr:number[] = [11, 22, 33]
第二种
let arr:Array<number> = [11, 22, 33]
1.5 元组类型
:::success 属于数组的一种 :::
let arr:[number, string] = [123, 'this']
1.6 枚举类型
enum Flag {
flag1,
flag2
}
enum Flag2 {
flag1 = 1,
flag2 = 2
}
let s:Flag = Flag.flag1
1.7 任意类型 any
let arr:any = 123
arr = 'this'
1.8 null 和 undefined
:::success 其他类型的子类型 :::
// 定义未赋值
let num:number | undefined
console.log(num)
// 可能是 number,null, undefined
let num:number | null | undefined
1.9 void
// 无返回值
function run():void {
console.log('run')
}
1.10 never 类型
:::success 是其他类型(包括 null 和 undefined)的子类型,代表从不会出现的值 :::
let a:never
a = 123 // Error
a = (() => { // OK
console.log()
})()
2. 类型断言
类型断言分两种方式:
- “尖括号”
- as 关键字
// 使用尖括号方式 let oneStr:any = "this is a string" // 定义一个 any 类型的变量 let len = oneStr.length // Error let len = (<string>oneStr).length
// 使用 as 关键字,推荐 let oneStr:any = "this is a string" let len = (oneStr as string).length
3. 泛型
泛型语法与Java类似。3.1 泛型函数
泛型函数的定义
泛型函数的定义如下:function sayHello<T>(arg: T):T { return arg }
泛型函数的使用
使用“尖括号”
使用类型推断let out = sayHello<string>("Hello TypeScript!")
TypeScript 会根据传入的参数类型自动确定 T 类型。let out = sayHello("Hello TypeScript"!)
3.2 泛型变量
将泛型作为变量类型的一部分,比如泛型数组等。function hello<T>(arg: T[]):T[] { console.log(arg.length) // arg 是 T 类型的数组,有 length 属性 let temp: [number, T] = [12, arg[0]] // T 作为 temp类型的组成部分 return arg }
4. 枚举
枚举可以定义一些名字有意义的常量。4.1 数字枚举
```typescript enum OrderStatus { Start = 1, Unpaid, Shipping, Shipped, Complete }
console.log(OrderStatus.Unpaid) // 2 console.log(OrderStatus.Shipping === 3) // true
<a name="8tT7R"></a>
### 4.2 字符串枚举
字符串枚举成员必须手动初始化。
```typescript
enum OrderStatusStr {
Start = "start",
Unpaid = "unpaid",
Shipping = "shipping",
Shipped = "shipped",
Complete = "complete"
}
console.log(OrderStatusStr.Shipping) // shipping
console.log(OrderStatusStr.Shipped === 'shipped') // true
4.3 反向映射
反射映射是数字枚举的一个技巧:
可以通过枚举的值,获取枚举中定义的各种常量名称。
enum OrderStatus {
Start = 1,
Unpaid,
Shipping,
Shipped,
Complete
}
const a = OrderStatus.Start // 1
const nameOfA = OrderStatus[a] // "Start"
console.log(nameOfA)
const nameOfB = OrderStatus[2] // "Unpaid"
console.log(nameOfB
5. symbol
在实际开发中,常量使用 symbol 值最大的好处就是:其他任何值都不可能有相同的值了,因此可以保证诸如特定字面量歌者特定的switch语句值可以按设计的方式工作。
const symbol = Symbol()
const obj = {
[symbol]: "symbol value"
}
console.log(obj[symbol]) // "symbol value"
6. iterator
当一个对象实现了 Symbol.iterator
方法时,这个对象是可迭代的,如 array、map、set、string、int32Array、uint32Array 等一些内置类型。对象上的 Symbol.iterator
函数负责返回供迭代的值。
使用 for...of...
语句可以遍历迭代的对象,调用对象上的 Symbol.iterator
方法。
const array = [233, 'hello', true]
for (let item of array) {
console.log(item) // 233, 'hello', true
}
:::danger
for...of...
和 for...in...
的最大区别:
二、TS 高级类型
1. interface
interface 的更多用法,会在后面的笔记中逐渐增加。
interface A {
a: number,
b: string,
c: number[]
}
let aVar:A = {
a : 29,
b : 'Mango',
c : [12, 12]
}
console.log(aVar)
2. 交叉类型
交叉类型是将多个类型合并为一个类型。 这让我们可以把现有的多种类型叠加到一起成为一种类型,它包含了所需的所有类型的特性。 例如, Person & Serializable & Loggable
同时是 Person
和 Serializable
和 Loggable
。 就是说这个类型的对象同时拥有了这三种类型的成员。
:::danger
- 不可以将基本类型用于交叉类型,否则会出现 never 类型
:::
```typescript interface A { a: number, b: string }// 基本类型不能交叉 type newType = number & string // 是一个 never 类型 let a: newType = 11 // Error
interface B { c: number, d: string } // 交叉类型, AB 即包含 A 也包含 B type AB = A & B
let ab =
官网例子:
```typescript
function extend<T, U>(first: T, second: U): T & U {
let result = <T & U>{};
for (let id in first) {
(<any>result)[id] = (<any>first)[id];
}
for (let id in second) {
if (!result.hasOwnProperty(id)) {
(<any>result)[id] = (<any>second)[id];
}
}
return result;
}
class Person {
constructor(public name: string) { }
}
interface Loggable {
log(): void;
}
class ConsoleLogger implements Loggable {
log() {
// ...
}
}
var jim = extend(new Person("Jim"), new ConsoleLogger());
var n = jim.name;
jim.log();
3. 联合类型
联合类型表示一个值可以是几种类型之一。 我们用竖线( |
)分隔每个类型,所以 number | string | boolean
表示一个值可以是 number
, string
,或 boolean
。
如果一个值是联合类型,我们只能访问此联合类型的所有类型里共有的成员。