一、编译
1. 命令行编译
- 第一步: 创建.ts文件
- 第二步: 全局安装
TypeScript 1
| npm install -g typescript
|
- 第三步: 使用命令行编译
2. 自动化编译
- 第一步: 创建
TypeScript编译配置文件
- 第二步: 监视目录的
.ts变化
- 第三步: 小优化
1
| tsc --noEmitOnError --watch
|
二、类型声明
1 2 3 4 5 6 7
| let a: string = "abc"; let b: number = 91; let c: boolean = true;
function count(x: number, y: number): number{ return x + y; }
|
三、类型推断
四、类型总览
1. JavaScript 中的数据类型
string
number
boolean
null
undefined
bigint
symbol
object
object包含:Array,Function,Date,Error等…
2. JavaScript 中的数据类型
- 上述所有类型
- 六个新类型
- `any
unknown
never
void
tuple
enum
- 两个用于自定义类型的方式
3. 注意
在JavaScript和TypeScript中内置构造函数:Number,String,Boolean可用于创建包装对象,日常开发少用,通常使用小写的类型
五、常用类型
1. any
1 2 3 4 5 6 7 8 9 10
| let a: any; a = 91; a = "abc"; a = true;
let b; b = 91; b = "abc"; b = true;
|
any类型不进行类型检查
1 2 3
| let c = true; let d: string = c; console.log(d);
|
any类型可赋值给任何类型
2. unknown
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| let a: unknown; let b: string;
a = 91; a = "abc"; a = true;
b= a;
a = "abc"; b = a;
if(typeof a === 'string'){ b = a; }
x = a as string;
x = <string>a;
|
unknown与any相似,但是不能直接赋值给其他变量,即便类型是相同的
1 2 3 4 5 6 7 8 9 10 11
| let a: string = 'hi'; a.toUpperCase();
let a: any = 'hi'; a.toUpperCase();
let a: unknown = 'hi'; a.toUpperCase();
(a as string).toUpperCase(); <string>a.toUpperCase();
|
unknown调用任何属性方法都会报错,与any恰恰相反
3. never
1. 几乎不用never限制变量,没有意义
2. 可用于限制函数。返回never的函数不能有可访问的终节点
1 2 3 4 5 6 7 8 9 10 11 12
| function test() : nerver { }
function test() : nerver { test() }
function test() : nerver { throw new Error("异常"); }
|
3. never一般为TypeScript主动推断出来的
1 2 3 4 5 6 7
| let a: string = "abc";
if(a === 'string') { console.log(a.toUpperCase()); }else{ console.log(a); }
|
4. void
void通常用于函数返回值声明,含义:函数返回空(undefined),调用者也不应依赖返回值进行任何操作
1 2 3 4 5
| function logMessage(msg: string) : void { console.log(msg); }
logMessage("hi");
|
1 2 3 4 5 6 7 8 9 10 11 12 13
| function test1() : void {
} let result1 = test1(); console.log(result1); if(result1){ }
function test2() : undefined { } let result2 = test2(); if(result2){ }
|
5. object
1. object和Object项目不常用
object不能存原始类型(number, boolean, string, null, undefined)只能存非原始类型
Object能存储可以调用到Object方法的类型(除了null和undefined)
2. 声明对象类型
1. 常用以下形式
1 2 3 4 5 6 7
| let Person = { name: string, age?: number } let Person = { name: string; age?: number } let Person = { name: string age?: number }
|
2. 索引签名
1 2 3 4 5 6 7
| let Person = { name: string age?: number [key: string]: any } Person = { name: "xxx", age: 20, city: "Beijin"}
|
3. 声明函数类型
1 2 3 4 5
| let count: (a: number, b: number) => number
count = function (x, y) { return x + y; }
|
TypeScript中的=>在函数声明时表示函数类型,描述其参数类型和返回类型
JavaScript中的=>表示箭头函数
4. 声明数组类型
1 2 3 4 5
| let arr1: string[]; let arr2: Array<number>;
arr1 = ['a', 'b']; arr2 = [12, 34];
|
6. tuple
元组是一种特殊的数组类型,可以存储固定数量的元素,并且每个元素的类型是已知的且可以不同,元组用于精确描述一组值的类型,?表示可选元素,...表示任意多个。
1 2 3
| let a: [string, number]; let b: [string, boolean?]; let c: [string, ...string[]];
|
7. enum
1. 数字枚举
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| enum Direction { Up, Down, Left, Right }
function walk(data: Direction) { if(data === Direction.Up){ console.log("向上走"); } if(data === Direction.Down){ console.log("向下走"); } if(data === Direction.Left){ console.log("向左走"); } if(data === Direction.Right){ console.log("向右走"); } }
Walk(Direction.Up);
|
成员值自动递增,且数字还具备反向映射的特点。
2. 字符串枚举
1 2 3 4 5 6 7 8 9
| enum Direction { Up = "up", Down = "down", Left = "left", Right = "right" }
let dir: Direction = Direction.Up; console.log(dir);
|
3. 常量枚举
1 2 3 4 5 6 7 8
| const enum Direction { Up, Down, Left, Right }
console.log(Direction.Up);
|
常量枚举使用const关键字定义,在编译时会被内联,避免生成额外代码
编译时内联:
TypeScript在编译时,会枚举成员引用替换为它的实际值而不是生成额外的枚举对象。可以减少JavaScript代码量,提高运行效率。
8. type
1. 基本用法
1 2 3
| type shuzi = number;
ket a: shuzi;
|
2. 联合类型
1 2 3 4 5 6 7
| type Status = number | string; type Gender = '男' | '女';
function printStatus(data: Status): void{ console.log(data) }
|
3. 交叉类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| type Area = { height: number width: numer };
type Address = { num: number cell: number room: string };
type House = Area & Address;
const house: House = { height: 100, weight: 100, num: 1, cel: 2, room: '702' }
|
9. 一种特殊情况
1 2 3 4 5 6 7 8
| function demo(): void{ return undefined; return 100; return false; return null; return []; }
|
1 2 3 4 5 6 7 8 9 10
| type LogFunc = () => void; const f1: LogFunc = function() { return undefined; return 100; return false; return null; return []; };
|
1 2 3 4
| const src = [1, 2, 3]; const dst = [0];
src.forEach((e1) => dst.push(e1))
|
forEach()的期望返回值是void,而push()的返回值是number。为了使类似的代码成立,而做了取舍
11. 类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| class Person { name: string; age: number; constructor(name: string, age: number){ this.name = name; this.age = age; } speak() { console.log(`名字:${this.name},年龄:${this.age}`); } }
class Student extends Person { grade: string; constructor(name: string, age: number, grade: string){ super(name, age); this.grade = grade; } study(){ console.log(`${this.name},正在学习`); } override speak() { console.log(`我的名字:${this.name},我的年龄:${this.age}`); } }
|
12. 属性修饰符
| 修饰符 |
含义 |
具体规则 |
public |
公开的 |
可以被:类内部,子类,类外部访问 |
protected |
受保护的 |
可以被:类内部,子类访问 |
private |
私有的 |
可以被:类内部访问 |
readonly |
只读属性 |
属性无法修改 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class Person { name: string; age: number; constructor(name: string, age: number){ this.name = name; this.age = age; } this.name = name; this.age = age; } }
class Person { constructor(public name: string, public age: number) {} }
|
12. 抽象类
抽象类无法实例化,意义在于可以被继承,抽象类里可以有普通方法,也可以有抽象方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| abstract class Package { constructer(public weight: number) {} abstract calculate(): number printPackage() { console.log("xxxx"); } } class StandardPackage extends Package { constructor( weight: number, public uniPrice: number ) { super(weight) } calculate(): number{ return this.weight * this.unitPrice; } }
|
13. interface
接口为类,对象,函数等规定一种契约,确保代码一致性和类型安全。只能定义格式,不能包含任何实现
1. 定义类结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| interface PersonInterface { name: string; age: number; speak(n: number): void }
class Person implements PersonInterface { constructor( public name: string, public age: number ) {} speak(n: number): void { for (let i = 0; i < n; i++) { console.log('xxxx') } } }
|
2. 定义对象结构
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| interface UserInterface { name: string; readonly gender: string; age?: number; run: (n: number) => void; } const user: UserInterface = { name: "zhangsan", gender: "男", age: 18, run(n) { console.log("xxx") } }
|
3. 定义函数结构
1 2 3 4 5 6 7
| interface CountInterface { (a: number, b: number): number; }
const count: CountInterface = (x, y) => { return x + y }
|
4. 接口的继承
1 2 3 4 5 6 7 8 9 10 11 12 13
| interface PersonInterface { name: string; age: number; } interface StudentInterface extends PersonInterface { grade: string; }
const stu: StudentInterface = { name: "xxx", age: 18, grade: "xxx" }
|
5. 接口的自动合并
1 2 3 4 5 6 7 8 9 10 11 12 13
| interface PersonInterface { name: string; age: number; } interface PersonInterface { gender: string; }
const p: PersonInterface = { name: "xxx", age: 18, gender: "xxx" }
|
14. 相似概念的区别
1. interface和type的区别
- 相同点:
interface和type都可以用于定义对象结构,两者在许多场景中是可以互换的。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| interface PersonInterface { name: string; age: number; speak(): void; } type PersonType = { name: string; age: number; speak(): void; }
let p1: PersonInterface = { name: "xxx", age: 18, speak(){ console.log("xxx"); } } let p2: PersonType = { name: "xxx", age: 18, speak(){ console.log("xxx"); } }
|
- 不同点:
interface :更专注于定义对象和类的结构,支持继承与合并。
type:可以自定义类型别名,联合类型,交叉类型,但不支持继承和自动合并。
2. interface和抽象类的区别
- 相同点:都用于定义一个类的格式
- 不同点:
interface:只能描述结构,不能有任何实现代码,一个类可以实现多个接口。
- 抽象类:既可以包括抽象方法,又可以包含具体方法,一个类只能继承一个抽象类。
六、泛型
泛型允许我们在定义函数,类或接口时,使用类型参数来表示未指定的类型,这些参数在具体使用时,才能被指定具体类型。泛型能让同一段代码适用于多种类型同时仍保证类型的安全性。
1. 泛型函数
1 2 3 4 5 6
| function logData<T,U>(data1: T, data2: U): T | U { return Data.now() % 2 ? data1 : data2; }
console.log(logData<number, bool>(1000, true)); console.log(logData<string, number>('hello', 666));
|
2. 泛型接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| interface PersonInterface<T> { name: string; age: number; extraInfo: T } type Home = { address: string; postalCode: number; } let p: PersonInterface<Home> = { name: "TOM", age: 18, extraInfo: { address: "xxxx", postalCode: 123485 } }
|
3. 泛型类
1 2 3 4 5 6 7 8 9 10 11 12
| class Person<T> { constructor( public name: string, public age: number, public extraInfo: T ) {} speak(){ console.log("xxxx"); } }
const p1 = new Person<number>("xxx", 18, 250);
|
七、类型声明文件
.d.ts文件为现有的javascript代码提供类型信息
1 2 3 4
| export function add(a, b){ return a + b; }
|
1 2 3
| declare function add(a: number, b: number): number; export(add)
|
八、装饰器