typescript是jiavascript的超集这里记录一些简单的用法,如深入层次的请查看官网。
typescript官网
typescript是属于渐进式的,如果对有的语法不太熟,也没关系,我们可以完全按照javascript的语法编写代码。
原始数据类型
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()
// Promise
// const error: string = 100
作用域问题:默认文件中的成员会作为全局成员,多个文件中有相同成员就会出现冲突。
解决办法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
元组
我们知道数组中元素的数据类型都一般是相同的(any[] 类型的数组可以不同),如果存储的元素数据类型不同,则需要使用元组。
元组中允许存储不同类型的元素,元组可以作为参数传递给函数。
const tuple: [number, string] = [18, 'zce']
const [age, name] = tuple
const entries: [string, number][] = Object.entries({
foo: 123,
bar: 456
})
const [key, value] = entries[0]
枚举(Enum)
标准的数字枚举
enum PostStatus {
Draft = 0,
Unpublished = 1,
Published = 2
}
数字枚举,枚举值自动基于前一个值自增
enum PostStatus {
Draft = 6,
Unpublished, // => 7
Published // => 8
}
字符串枚举
enum PostStatus {
Draft = 'aaa',
Unpublished = 'bbb',
Published = 'ccc'
}
// 常量枚举,不会侵入编译结果
const enum PostStatus {
Draft,
Unpublished,
Published
}
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'
}
const func2: (a: number, b: number) => string = function (a: number, b: number): string {
return 'func2'
}
任意类型(弱类型)
function stringify (value: any) {
return JSON.stringify(value)
}
let foo: any = 'string'
any 类型是不安全的
接口
任意值对象在代码里
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//只读
}
const hello: Post = {
title: 'Hello TypeScript',
content: 'A javascript superset',
summary: 'A javascript'
}
interface Cache {
[prop: string]: string
}
//定义对象属性名是字符串,值也是字符串
const cache: Cache = {}
cache.foo = 'value1'
cache.bar = 'value2'
class
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 //私有 当成员被标记为private时,它就不能在声明它的类的外部访问
protected gender: boolean //protected和private类似,但是,protected成员在派生类中可以访问
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 {
// 只读成员
protected readonly gender: boolean
private constructor (name: string, age: number) {
super(name, age)
this.gender = true;//必须初始赋值
console.log(this.gender)
}
static create (name: string, age: number) {
return new Student(name, age)
}
}
const tom = new Person('tom', 18)
console.log(tom.name)
// console.log(tom.age)
// console.log(tom.gender)
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')
有的库默认没有typescript支持,需要下载对应支持库。
如lodash,需要安装@types/lodash。
tsconfig.json文件配置详情查看:typescript官网配置说明