是基于JavaScript扩展的一门语言,是JavaScript的超集
在JavaScript原有基础上增加了一套强大的类型系统和对ES6的支持,最终TypeSrcipt会被编译回JavaScript,任何一个JavaScript运行环境都支持TypeSrcipt
原始类型检查
在变量后加 : 类型
const a: string = 'string'
const b: number = 100
const c: boolean = true
const d: void = undefined
const e: undefined = undefined
const f: null = null
标准库
是内置对象所对应的声明,需要额外声明标准库在tsconfig.json文件里lib
{
"compilerOptions": {
"target": "es5",
"lib": ["ES2015", "DOM"], // 声明es2015和dom
}
}
设置中文错误提示
编译后错误提示 命令行:yarn tsc --locale zh-CN
vsc中文错误提示: setting -> typescript locale
Object类型
ts中Object类型是泛指所有非原始类型,Object对象类型应该用接口声明
const foo1: object = function () {} // 可以是函数
const foo2: object = {} // 可以是对象
const foo3: object = [] // 可以是数组
// 指定obj1对象里面 只能有foo和bar属性
// 不能多不能少 并且两个属性的类型要对应上
const obj1: { foo: number, bar: string } = { bar: '123', foo: 10 }
Array类型
const arr1: Array<number> = [1, 2, 3]
const arr2: number[] = [1, 2, 3]
function sum (...args: number[]) {
// ts的检查节省参数类型检查
return args.reduce((prev, current) => prev + current, 0)
}
// sum(1, '2', '3') 类型错误编译不通过sum(1, 2, 3)
元组类型
定义数组的元素类型和个数,多用于函数返回
枚举类型
// 常量枚举 枚举类型
// 前面加const
// 常量枚举只是做枚举值的替换
const enum PostStatus {
// 成员值可以不指定 默认从0开始累加
// 如果前一个成员有指定值 后面就从这个指定值累加
Draft, // 默认0
unpublished = 5,
Published, // 6
// other = 'other',
// 成员累加只能是数字
other1 = 'other1'
}
const post = {
title: 'Hello TypeScript',
content: 'TypeScript is a typed superset of JavaScript',
status: PostStatus.Draft
}
// 如果是普通枚举就可以实现通过枚举值找枚举键
// console.log(PostStatus[5]) // unpublished
函数类型
// 函数声明的例子
// 两种方式实现参数可选的
// 一个是 c?: number 这种方式还可以设置如果传了必须是数字
// 另一是设置参数默认值 c: number = 10
// ...args 可以接收剩下的任意参数
// 必须返回一个字符串
function func1 (a: number, b: number, c: number = 10, ...args: number[]): string {
// return 10
return 'func1'
}
// func1(100) // 至少两个两个参数
// 第三个参数可选 默认值10func1(100, 200)
// 第三个参数必须是数字// func1(100, 200 , 'ss')
func1(100, 200, 300, 400) // ...args 接收剩余参数
// 函数表达式
const func2: (a: number, b: number) => string = function(a: number, b: number): string {
return 'func2'
}
任意类型
any表示任意类型,ts不会对any类型进行类型检查,所以any类型是不安全的,any主要是用于兼容旧的代码写法
function stringifyJSON(value: any) {
// JONS.stringify可以接收任意类型 所以在ts里用any声明
return JSON.stringify(value)
}
隐式类型推断
如果没有在变量声明时指定类型,ts会根据声明时的初始值来推断变量的类型,效果和指定类型一样,如果没有初始值就无法推断,认为是any类型
应该为每个变量指定类型,方便代码阅读
let age = 18 // 自动推断是 number
// age = 'tom' // 检查类型不对
let name // 没有初始值 推断不了 认为是any 不作类型检查
name = 20
name = 'tom'
类型断言
明确代码执行结果的变量类型,声明在typeScript上
const nums = [1,2,3,4]
const res = nums.find(i => i > 0)
const num1 = res as number // 进行类型断言
// const square = res * res // typeScript 不确定res是数字有可能是undefined
const square = num1 * num1
接口
用于对象的约束,规定对象中要有哪些属性,这些属性是什么类型
// 接口规定实现这个接口的对象要有的成员和对应类型
// 规定个数和对应的类型
// 可选成员可以没有
// 动态成员外可以额外
// 只读成员不可以修改 只可以初始化
interface Post {
title: string,
content: string,
viewCount: number,
subTitle?: string, // 可选成员 value是undefined
readonly summary: string
// 动态成员用兼容其他成员
[key: string]: string | number | undefined
}
function printPost (post: Post) {
console.log(post.title)
console.log(post.content)
}
const post: Post = ({
title: 'title',
content: 'content',
viewCount: 10,
// subTitle: 'subTitle', // 因为可选成员可以没有
summary: 'summary',
other: 'other' // 因为动态成员所以可以多
})
printPost(post)
// 只读成员不可以改
// post.summary = 'otherSummary'
类
是用来描述一类事物具有对象的抽象成员,ES6中用class来声明类,typeScript中对类进行了增强
-
构造函数中赋值的成员 要在类中声明
-
成员声明时可以指定类型
-
可以指定只读成员,只能初始化 或者 构造器赋值
-
可以对类的成员和构造器增加访问三种修饰符
-
private 私有成员 只能当前类访问
-
protected 保护成员 只能当前类和子类访问
-
public 公共成员 都可以访问
class Person { // 可以对类的成员增加访问修饰符 // private 私有成员 只能当前类访问 // protected 保护成员 只能当前类和子类 // public 公共成员 都可以访问 // 默认成员就是public public name: string // 可以在声明时赋值初始值 private age: number // 也可以在构造函数中赋值 protected readonly gender: boolean = true // 构造函数也可以添加访问修饰符 // 默认是public // protect构造函数 只能用于当前类和被继承 constructor (name: string, age: number) { // 构造函数中赋值的成员 要在类中声明 this.name = name this.age = age } sayHi (msg: string): void { console.log(`hello, ${this.name}, ${msg}`) console.log(this.age) // 当前类可以访问 } } class Student extends Person { // 私有构造函数 不能在外边创建实例 private constructor(name: string, age: number) { super(name, age) // 子类可以访问父类保护成员 console.log(this.gender) // 不能修改只读成员 // this.gender = false } static create(name: string, age: number) { return new Student(name, age) } } const tom = new Person('tom', 20) // console.log(tom.age) // 私有成员不能访问 // console.log(tom.gender) // 保护成员不能访问 // 私有构造函数 不能外边创建实例 // const jack = new Student('jack', 20) const jack = Student.create('jack', 22)
类和接口
interface Eat {
eat (food: string): void
}
interface Run {
run (distance: string): void
}
class Person implements Eat,Run {
eat (food: string):void {
console.log(`人吃 ${food}`)
}
run (distance: string):void {
console.log(`人走 ${distance}`)
}
}
class Animal implements Eat,Run {
eat (food: string):void {
console.log(`动物吃 ${food}`)
}
run (distance: string):void {
console.log(`动物走 ${distance}`)
}}
class Car implements Run {
run (distance: string):void {
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) // 子类实现的抽象方法
泛型
将声明时无法确定的参数类型定义成泛型,到使用的时候,传入泛型的类型来指定参数的类型
// 使用泛型 T 来代表一个类型
// 这个类型要调用时传入来确定
function createArray<T> (length: number, value: T): T[] {
const arr = Array<T>(length).fill(value)
return arr
}
// 调用时传入泛型 传入的泛型决定类型
const res1 = createArray<number>(3, 200)
const res2 = createArray<string>(3, 'aaa')