1.typescript优势
1.1 提前暴露问题,在开发阶段发现90%的问题
1.2 代码提示更友好
1.3 重构方便
1.4 减少类型判断
( 强类型,语言类型约束,字段声明类型
不允许隐式类型转换。‘100’-50 ,+‘50’)
2.安装typescript环境
可以使用ts-node插件来解决这个问题,有了这个插件,我们就不用再编译了,而使用ts-node就可以直接看到编写结果。
npm install ts-node //安装
ts-node ***.js //执行ts查看结果
yarn init --yes // 初始化package.json
yarn add typescript --dev // 安装ts
yarn tsc -int //生成tsconfig.json配置文件
tsc 文件名.ts // 把ts文件编译成js,方便浏览器调用
tsc -w侦听整个项目,自动编译js
yarn tsc --locale zh-CN // 中文错误消息提示
“lib”: [“ES2015”,“DOM”], /* 标准库Specify library files to be included in the compilation. */
"outDir": "./dist", /* Redirect output structure to the directory. */
"rootDir": "./src", /*导入文件*/
"strictNullChecks": true, /* Enable strict null checks. 变量不能为空*/
tsc hello.js // 编译单个文件
yarn tsc // 编译整个文件夹
npm install -g ts-node
运行:ts-node home.ts // 可以允许ts文件
any、void、never、unknown、、tuple、enum枚举、
1.按照js语法
const hello = (name:any) =>{
console.log(hello, ${name}
)
}
hello(100)
2.数据类型
// 数据类型
const a: string = ‘foobar’
const b: number = 100
const c: boolean = true
const e: void = undefined // 空值,函数没有返回值时用来标记
const f: null = null
const g: undefined = undefined
const h: symbol = Symbol()
const a = 123
export { a }
//export default a; //仅有一个
4.object
export {}
const foo = function(){}
const obj: {foo:number, bar:string} = {foo:123, bar:‘string’}
5 数组类型
const arr1: Array = [1,2,3]
const arr2: number[] = [1,2,3]
//
function sum(…args:number[]){
return args.reduce((prev,current)=> prev+current, 0)
}
sum(1, 2, 3)
- 元祖,明确长度,类型的数组
export {}
const tuple:[number,string]=[1, ‘dhk’]
const age = tuple[0]
// 解构赋值获取
const [a,b]=tuple
Object.entries({
foo:123,
bar:456
})
7.枚举
export {}
const enum PostStatus {
// 如果不赋值,默认从0开始,
// Draft,
// Unpublished,
// Publish
// 只赋值第一个,后面默认增加
// Draft = 7,
// Unpublished,
// Publish
Draft = 0,
Unpublished = 1,
Publish = 2
// 字符串
// Draft = 'aaa',
// Unpublished = 'bbb',
// Publish = 'ccc'
}
const post = {
title:‘hello typescript’,
content:‘typescript is typed superset of javascript’,
status: 2 //1 //0
}
8.函数类型
export {}
// ?可选参数
function func1(a:number, b?:number, …rest:number[]): string{
return ‘func1’
}
func1(100,200)
func1(100)
- 任意类型
export{}
function stringify(value:any){
return JSON.stringify(value)
}
stringify(‘string’)
- 隐式类型推断
export{}
let age = 18
// age = ‘string’ //Type ‘string’ is not assignable to type ‘number’.
let foo
foo = 100
foo = ‘duan’
11 类型断言
// 假定numbs来自一个明确的接口
export{}
const nums = [110, 120, 119, 112]
const res = nums.find(i=> i>0)
const num1 = res as number
const num2 = res // 这种语法,在react的jsx中冲突
12 接口:约束对象的解构
export{}
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 super’
})
13接口,可选成员、只读成员、动态成员
export{}
interface Post {
// 字段之间可以用, ; 或者不加
title:string
content:string
subtitle?:string // 可选
readonly summary: string
}
const hello13: Post= {
title: ‘hello typescript’,
content: ‘a javascript super’,
summary:‘不可修改’
}
// hello13.summary = ‘other’ //Cannot assign to ‘summary’ because it is a read-only property.ts(2540)
// 新建接口,动态
interface Cache {
[key:string]:string
}
const cache: Cache = {
foo : ‘value1’,
bar : ‘value2’
}
14 类 class
export{}
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}
)
}
}
15.类的访问修饰符
// 类的访问修饰符
// 1.public 默认是
// 2.private 类内部才能访问
// 3.protected // 只允许子类访问
export{}
class Person {
// 类必须有初始值,可以在这里或者构造函数中赋值
public name:string // = ‘init name’
private age:number // 只能类的内部方法可以访问private
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)
}
}
const tom = new Person(‘tom’, 18)
console.log(tom.name)
// console.log(tom.age) // Property ‘age’ is private and only accessible within class ‘Person’.ts(2341)
// console.log(tom.gender) // Property ‘gender’ is protected and only accessible within class ‘Person’ and its subclasses.ts(2445)
class Student extends Person{
// 不允许子类继承,用private
static dhk:number=1
private constructor (name:string, age:number){
super(name, age)
// protected 可以在子类访问到
console.log(this.gender)
}
}
const jack = Student.dhk
console.log(jack)
tom.name=‘dhk’
16 类的访问修饰符
// 1.public 默认是
// 2.private 类内部才能访问
// 3.protected // 只允许子类访问
// 4.readonly 放在上面3个后面
export{}
class Person {
// 类必须有初始值,可以在这里或者构造函数中赋值
public name:string // = ‘init name’
private age:number // 只能类的内部方法可以访问private
protected readonly 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
static dhk:number=1
private constructor (name:string, age:number){
super(name, age)
// protected 可以在子类访问到
console.log(this.gender)
// this.gender = false // Cannot assign to ‘gender’ because it is a read-only property.ts(2540)
}
}
const jack = Student.dhk
- 类与接口
接口的方法一般为空的, 必须重写才能使用
export {} // 确保其他实例没有冲突
// 一个接口一个功能
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}
)
}
}
- 抽象类
export{} // 确保其他示例没有冲突
// 被定义抽象类后,只能被继承,不能用new 创建实例对象
abstract class Animal {
eat (food: string):void {
console.log(呼噜呼噜的吃: ${food}
)
}
// 抽象方法,子类必须去实现这个方法
// 可以在子类上点ctrl+类名,自动写这个方法
abstract run (distance: number):void
}
class Dog extends Animal {
run(distance: number): void {
console.log(‘四脚爬行’, distance)
// throw new Error(“Method not implemented.”)
}
}
const dog = new Dog()
dog.eat(‘大便’)
dog.run(100)
- 泛型 //入参类型和return类型一致
export {}
function createNumberArray(length:number,value:number):number[]{
const arr = Array(length).fill(value)
return arr
}
const res = createNumberArray(3,100)
// res = [100,100,100] 普通指定类型
// 下面是泛型
function createArray(length:number, value:T):T[]{
const arr = Array(length).fill(value)
return arr
}
const res2 = createArray(3,‘fooooo’)
- 类型声明,第三方插件类型声明模块
// yard add @types/lodash
// 如果第三方插件没有类型声明模块,就自己写declare
// declare function camelCase (input: string): string
import { camelCase } from ‘lodash’
import qs from ‘query-string’
qs.parse(‘?key=value&key2=value2’)
// console.log(myqs)
const res = camelCase(‘hello typed’)
// console.log(res)
n.flow.js 类型声明
yarn init --yes //初始化package.json
yarn add flow-bin --dev // 开发依赖安装
flow init
01-getting-started.js
// @flow
function sun(a: number, b: Number){
return a+b
}
sun(‘100’,100)
2.组件开发
3.小程序