TypeScript
区别
JavaScript 与 TypeScript 的区别 TypeScript 是 JavaScript 的超集,扩展了 JavaScript 的语法,因此现有的 JavaScript 代码可与 TypeScript 一起工作无需任何修改,TypeScript 通过类型注解提供编译时的静态类型检查。
TypeScript 可处理已有的 JavaScript 代码,并只对其中的 TypeScript 代码进行编译。
安装
// 安装包
npm install typescript
// 编译
tsc filename.ts
// 配置 出现tsconfig.ts 文件
tsc --init
{
"compilerOptions": {
"lib" : ["ES2015", "DOM", "ES2017"],
"module": "commonjs",
// 配置编译目标时使用的模块化标准
"outDir": "./dist",
// 编译结果的文件夹
"rootDir": "src",
"strict": true,
"target": "es6"
// 配置编译时目标使用的代码标准
},
"include": ["./src"]
// 编译的文件夹
// "files": ["./src/index.ts"]
// 编译某一个文件
}
可以完全按照 JavaScript 标准语法编写代码
const hello = (name: any) => {
console.log(`Hello, ${name}`)
}
hello('TypeScript')
原始数据类型
const a: string = 'foobar'
const b: number = 100 // NaN Infinity
const c: boolean = true // false
// 在非严格模式(strictNullChecks)下,
// string, number, boolean 都可以为空
// const d: string = null
// const d: number = null
// const d: boolean = null
const e: void = undefined
const f: null = null
const g: undefined = undefined
// Symbol 是 ES2015 标准中定义的成员,
// 使用它的前提是必须确保有对应的 ES2015 标准库引用
// 也就是 tsconfig.json 中的 lib 选项必须包含 ES2015
const h: symbol = Symbol()
作用域问题
默认文件中的成员会作为全局成员 多个文件中有相同成员就会出现冲突
解决办法1: IIFE 提供独立作用域
(function () {
const a = 123
})()
// 解决办法2: 在当前文件使用 export,也就是把当前文件变成一个模块
// 模块有单独的作用域
const a = 123
export {}
Object 类型
// object 类型是指除了原始类型以外的其它类型
const foo: object = function () {} // [] // {}
// 如果需要明确限制对象类型,则应该使用这种类型对象字面量的语法,或者是「接口」
const obj: { foo: number, bar: string } = { foo: 123, bar: 'string' }
数组类型
// 数组类型的两种表示方式
const arr1: Array<number> = [1, 2, 3]
const arr2: number[] = [1, 2, 3]
// 如果是 JS,需要判断是不是每个成员都是数字
// 使用 TS,类型有保障,不用添加类型判断
function sum (...args: number[]) {
return args.reduce((prev, current) => prev + current, 0)
}
sum(1, 2, 3) // => 6
元组(Tuple)固定长度 结构
const tuple: [number, string] = [18, 'zce']
const age = tuple[0]
const name = tuple[1]
const [age, name] = tuple
枚举(Enum)
const enum PostStatus {
Draft = 0,
Unpublished = 1,
Published = 2
}
const post = {
title: 'Hello TypeScript',
content: 'TypeScript is a typed superset of JavaScript.',
status: PostStatus.Draft // 3 // 1 // 0
}
函数类型
function func1 (a: number, b: number = 10, ...rest: number[]): string {
return 'func1'
}
func1(100, 200)
func1(100)
func1(100, 200, 300)
任意类型(弱类型)
any 类型是不安全的
function stringify (value: any) {
return JSON.stringify(value)
}
stringify('string')
stringify(100)
stringify(true)
接口
interface Post {
title: string
content: string
}
function printPost (post: Post) {
console.log(post.title)
console.log(post.content)
}
printPost({
title: 'Hello TypeScript',
content: 'A javascript superset'
})
可选成员、只读成员、动态成员
interface Post {
title: string
content: string
subtitle?: string // 可选
readonly summary: string // 只读
}
// 对象的key必须是string
interface Cache {
[prop: string]: string
}
const cache: Cache = {}
cache.foo = 'value1'
cache.bar = 'value2'
类
基本使用
class Person {
name: string // = 'init name'
age: number
constructor (name: string, age: number) {
this.name = name
this.age = age
}
sayHi (msg: string): void {
console.log(`I am ${this.name}, ${msg}`)
}
}
类的访问修饰符
class Person {
public name: string // = 'init name'
private age: number
protected gender: boolean //只允许子类访问
constructor (name: string, age: number) {
this.name = name
this.age = age
this.gender = true
}
sayHi (msg: string): void {
console.log(`I am ${this.name}, ${msg}`)
console.log(this.age)
}
}
class Student extends Person {
// 不可以访问和继承
private constructor (name: string, age: number) {
super(name, age)
console.log(this.gender)
}
static create (name: string, age: number) {
return new Student(name, age)
}
}
const tom = new Person('tom', 18)
const jack = Student.create('jack', 18)
类与接口
- 不包含具体的实现
interface Eat {
eat (food: string): void
}
interface Run {
run (distance: number): void
}
class Person implements Eat, Run {
eat (food: string): void {
console.log(`优雅的进餐: ${food}`)
}
run (distance: number) {
console.log(`直立行走: ${distance}`)
}
}
class Animal implements Eat, Run {
eat (food: string): void {
console.log(`呼噜呼噜的吃: ${food}`)
}
run (distance: number) {
console.log(`爬行: ${distance}`)
}
}
抽象类
- 有具体的实现
abstract class Animal {
eat (food: string): void {
console.log(`呼噜呼噜的吃: ${food}`)
}
abstract run (distance: number): void
}
class Dog extends Animal {
run(distance: number): void {
console.log('四脚爬行', distance)
}
}
const d = new Dog()
d.eat('嗯西马')
d.run(100)
泛型
不指定具体的类型,传入的时候确定类型
function createNumberArray (length: number, value: number): number[] {
const arr = Array<number>(length).fill(value)
return arr
}
function createStringArray (length: number, value: string): string[] {
const arr = Array<string>(length).fill(value)
return arr
}
function createArray<T> (length: number, value: T): T[] {
const arr = Array<T>(length).fill(value)
return arr
}
const res = createNumberArray(3, 100)
// res => [100, 100, 100]
const res = createArray<string>(3, 'foo')