快速上手
- yarn init --yes
- yarn add typescript --dev
- yarn tsc path // 文件
- 编译好的注解会自动去掉
配置文件
生成配置文件:
yarn tsc --init 生成 tsconfig.js 配置文件
tsconfig.js 配置文件内
{
"target": "es5", // 输出转换位哪种特性的语法
"module": "common.js" // 输出的代码会才用什么样的方式进行模块化,目前使用的是 common.js ,就是导入导出会使用 require 方式进行引用输出
"outDir": "./" // 来设置编译结果输出的文件夹
"rootDir": "./", // 用来设置原代码的文件夹
"sourceMap": true, // 设置为 true 时,开启源代码映射, 开启后, 可以通过调试 souceMap 文件来进行测试,
"strict": true, // 严格模式, 作用是开启所有严格检查模式选项, 在严格模式下需要为每个类型增加一个注解,没有的话会报错
}
通过 yarn tsc path 指定文件时, 配合文件 tsconfig.js 不会生效, 运行 yarn tsc 会生效
TypeScript 6中原始数据类型
const a: string = "foo"
const b: number = 100 // NaN Infinity
const c: boolean = true // false
// const e: void = null // 严格模式下只能为 undefined
const e: void = undefined
const f: null = null
const g: undefined = undefined
const h: symbol = Symbol() // 报错 es6当中新增的, ES5 代码库中没有, 解决方法两种, 1.target 值改为 es2015 2.将 es2015 添加到 libs 标准库选项中
// 标准库就是内置对象对应的声明
TypeScript 中文错误消息
yarn tsc --local zh-CN
TypeScript 作用域问题
两个同目录的文件夹内,定义相同的变量会报错,解决方式如下:
// 1.立即执行函数
// (function(){
// const a = 123
// })()
// 使用 export
const a = 123
export {}
TypeScript Object 类型
object 类型不只指对象{},而是原始数据类型之外的其他类型
export {} // 确保跟其他示例没有成员冲突
// object 类型不只指对象, 而是除了原始数据类型之外的其他类型
const foo: object = function(){} // {} // []
// 对象字面量方式, 不推荐使用。 推荐使用接口方式, 下面介绍
const obj:{foo:number, bar:string} = {foo:123,bar:"123"} // 结构必须完全一样
TypeScript 数组类型
// 和 flow 模式完全一样
// export {}
const arr1: Array<number> = [1]
const arr2: number[] = [2,3,4]
// --------------------
function sum(...args: number[]){
return args.reduce((prev,current) => prev + current + 0)
}
sum(1,2,3)
TypeScript 元祖类型
元祖类型:一种特殊的数据结构,元祖就是明确元素数量以及每个元素类型的数组
// 对象字面量的形式进行定义
const tuple: [number,string] = [1,'2']
// const age = tuple[0]
// const name = tuple[1]
const [age,name] = tuple
TypeScript 函数类型
javaScript 中有两种定义函数的方式, 一种是函数声明, 一种是函数表达式,函数声明较为简单
// 函数声明
function func1(a:number,b:number,c?:number,...rest:number[]): string{
return 'func1'
}
// 参数个数也必须完全相同, 参数会按照位置进行传递
func1(1,2)
func1(100,200,300)
// 函数表达式. 和下面一样
const func2 = function(a:number,b:number):string{
return 'func2'
}
// 函数表达式
const func3:(a:number,b:number)=>string = function(a:number,b:number):string{
return 'func2'
}
TypeScript 任意类型
function stringify(value:any){
return JSON.stringify(value)
}
stringify('string')
stringify(100)
stringify(true)
let foo:any = 'string'
foo = 100
foo.bar() // 语法上不会报错, 注意是语法上
TypeScript 隐式类型推断
let age = 18 // 此时age 设置为 number 类型
age = "string" // 语法报错, 因为age已经被隐式类型推断为 number
let foo // foo 被推断为 any 类型
foo = 100 // 都不会报错
foo = "string" // 都不会报错
TypeScript 类型断言
js 断言方式有两种, 一种是 as 的方式, 一种是 <> 方式, <> 方式在jsx 中不能使用, 会有语法冲突
// 假定这个 nums 来自一个明确的接口
const nums = [100, 200, 300,400]
const res = nums.find(i => i > 0) // 返回值为 number 或 undefind
// 类型断言方式有两种
// 一种 as 方式
const num1 = res as number
// 一种尖括号方式<>
const num2 = <number>res // jsx 下不能使用
TypeScript 接口 interface
接口 可以理解为一种规范, 或者一种契约,抽象的概念
interface Post {
title:string
content: string
subtitle?: string // 可选成员
readonly summary: string // 只读成员
}
function printPoint(post: Post){
console.log(post.title)
console.log(post.content)
}
printPoint({
title:"interface",
content: "hello",
summary:"摘要"
})
// ----------------
// 动态成员
interface Cache {
[prop:string]:string
}
const cache:Cache = {}
cache.foo = 'value'
cache.age = 2 // 报错,所有的成员为 string 类型
TypeScript 类Classes
类的作用可以用来描述一类事物的抽象特征,用来描述一类对象的抽象成员 , ES6 之前函数 + 原型 模拟实现类,ES6 开始,javaScript 中有了专门的 class, TypeScript 增加了 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}`)
}
}
TypeScript 类的访问修饰符
三个访问修饰符, public private protected 用来控制类当中的成员可访问级别。
class Person {
public name: string // = 'init name' // 类属性在使用之前,必须现在类型中声明, 目的为了给类的属性增加标注
private age: number // 类的属性必须要有一个初始值, 可以通过 = 去赋值 , 活在在构造函数中初始化
protected gender: boolean // protected 受保护的, 指的是,只允许再子类中访问
constructor (name: string, age:number){
this.name = name
this.age = age
this.gender = true
}
sayHi(msg: string): void{ // TypeScript 中的void 是一个正确的类型,告诉开发人员这个函数返回 undefined
console.log(`I am ${this.name}, ${msg}`)
}
}
const tom = new Person('tom',18)
console.log(tom.name)
// console.log(tom.age) // 报错
// console.log(tom.gender) // 报错。 gender 受保护的
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 jack = Student.create('jack', 18)
TypeScript 类的只读属性
readonly 只读属性 , 在能在内部赋值 , 不能修改
TypeScript 类与接口
// 接口越简单越好
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 只能继承不能通过new 的方式创建
abstract class Animal {
eat(food:string):void{
console.log(`呼噜吃:${food}`)
}
abstract run (distance: number):void // 父类要是有 abstract 的, 子类必须要实现
}
class Dog extends Animal {
run(distance: number): void {
console.log(`四角爬行`, distance)
}
}
const d = new Dog()
d.eat('草')
d.run(100)
TypeScript 泛型 Generics
泛型就是指我们在定义函数或类的时候, 在声明时没有定义指定的类型。 通过传参的形式来实行
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 res2 = createArray<string>(3,'2')
TypeScript 类型声明(Type Declaration)
TypeScript 中引入第三方模块, 需要引入对应的声明文件, 没有的话需要自己定义
import { camelCase } from 'loadsh'
declare function camelCase (input:string): string // 定义对应的模块
const res = camelCase('hello typed')
export {} // 确保跟其他示例没有成员冲突