强类型 弱类型 => 类型安全角度
- 强类型是在编译阶段检查语法,弱类型是在运行阶段检查语法
- 强类型不允许随意的隐式类型转换
静态类型 动态类型 => 类型检查角度
- 动态类型 运行阶段才能明细类型 变量没有类型 存放的值有类型 js
- 静态类型 编译的时候就确定了类型
js是动态类型弱类型语言
- 弱类型语言的问题
-----运行阶段才能发现异常 - 强类型语言的问题
1.错误更早暴露
2.代码提示更加智能,编码更准确
- 重构更稳固
- 减少不必要类型判断
Flow js类型检查器
- 通过类型注解检查语法
- 安装 cnpm i flow-bin --dev
flow init 初始化配置文件
flow启动检查
使用
vscode setting配置中搜索javascript valid 关闭语法检测
// @flow
function sum(a:number,b:number){
return a+b
}
sum(100+200)
sum('100',200)
// References:
// index.js:2:16
// 2| function sum(a:number,b:number){
// ^^^^^^ [2]
去注解
方式1
- cnpm i flow-remove-types -g 去注解
- flow-remove-types . -d dist //将js去除注解输出到dist目录
方式2 - cnpm i @babel/core @babel/cli @babel/preset-flow -g
- babelrc配置 "presets": ["@babel/preset-flow"]
- babel index.js -d dest 输出js
flow 开发插件
- Flow Language Support 代码编辑器检查flow语法
flow 类型推断
// @flow
function sum(m,n){
return m*n
}
sum('100','10')
类型
// @flow
function sum(m, n) {
return m * n
}
sum('100', '10')
//原始类型
let a: string = '1' //变量类型
let b: number = NaN //Infinify 1
let c: boolean = false
let d: null = null
let e: void = undefined
let f: symbol = Symbol()
//数组
const arr: Array<number> = [1, 2, 3] //数字组成的数组
const arr2: number[] = [1, 2, 3] //数字组成的数组
const bar: [string, number] = ['1', 1] //字符串数字组成的数组 固定长度数组 元组
//对象
const obj1: { foo: string, bar: number } = { foo: '1', bar: 1 }
const obj2: { foo?: string, bar: number } = { bar: 1 } //?可选
const obj3: { [string]: string } = {} //允许任意个数的键,键和值为任意字符串
//函数
function foo(a: string): number { //返回值类型
return 1
}
function foo2(callback: (string, boolean) => void) { //回调函数类型
callback('1', true)
}
foo2(function (str, m) {
})
// 特殊类型
const aa: 'foo' = 'foo'
const type: 'danger' | 'success' | 'warning' = 'success'
const bb: string | number = 'aaa'
type StringorNumber = string | number
const cc:StringorNumber = 1
//maybe类型 可以为空
const gender : ?number = undefined //null
const gender2 : ?number = null
//mixed 类型 所有类型的联合类型 是一个具体类型 编译阶段会检查
function add(value:mixed){
value*value
}
add(1)
add('1')
add(true)
//any类型 接受所有类型 弱类型 编译阶段不会检查
function add2(value:any){
value*value
}
add2(1)
add2('1')
add2(true)
ts
- cnpm i typescript
- tsc index.ts编译对应js
- tsc --init 初始化配置文件 tsc运行项目配置文件才会生效
- 引用内置对象,需要引用对应标准库,如es6新特性,需要 "lib": ["ES2015","DOM"], DOM为了防止DOM标准库被覆盖
- tsc --locale zh-CN使用中文错误提示
类型
//与flow区别 三种类型允许为空 配置文件关闭严格模板 null/undefined
const a: string = null
const b: number = 2
const c: boolean = true
const d: void = null //undefined 严格模式只能是undefined
const e: null = null
const g: undefined = undefined
const h: symbol = Symbol()
//对象
const fn: object = function () { } //对象类型 包括函数 数组
const obj: { foo: number, bar: boolean } = { foo: 1, bar: true }
//数组
const arr: Array<number> = [1, 2, 3]
const arr2: number[] = [1, 2, 3]
//元组 固定长度的数组
const arr3: [number, string] = [1, '2']
//枚举 加上const为常量枚举
const enum statusPo {
Draft = 1,
publish = 2
}
const obj2 = {
a: statusPo.Draft
}
//函数
function fun(a: number, b?: number, ...rest: number[]): string {
return '222'
}
const fun2: (a: number, b: number) => string = function (a: number, b: number): string {
return '111'
}
fun(1, 2, 4, 5, 6, 7)
//任意类型
const u:any = 1
//类型推断
let vv = '111' //string
let vv2 //any
断言
//断言
const arr4 = [1, 2, 3, 4,6,119]
const res = arr4.find(item => item > 0)
// const sq = res * res //res为数字或undefined
//方式1
const num1 = res as number //断言结果一定为数字
//方式2
const num2 = <number>res //jsx下与标签语法冲突 不能使用
接口
//接口 约束对象的结构
interface Post{
title:string
content:string,
subTitle?:string,
readonly summary:string
}
function printPage(post:Post){
console.log(post.title)
console.log(post.content)
}
printPage({title:'1',content:'111',summary:'1'})
const page:Post = {title:'1',content:'111',summary:'1'}
page.summary = '2222' //不能修改只读属性
//动态成员
interface Caches{
[key:string]:string
}
const cache:Caches = {}
cache.foo = '1'
cache.bar = '2'
类与接口
//类与接口
interface Eat {
eat(food: string): void //声明方法及类型 类中去实现具体内容
}
interface Run {
run(distance: number): void
}
class Animal implements Eat, Run {
eat(food: string): void {
console.log('咕噜的吃', food)
}
run(distance: number) {
console.log('爬行', distance)
}
}
class Per implements Eat, Run {
eat(food: string): void {
console.log('优雅的吃', food)
}
run(distance: number) {
console.log('直立行走', distance)
}
}
抽象类
//抽象类
abstract class An { //抽象类只能被继承,不能使用new创建对象
eat(food: string): void {
console.log('咕噜的吃', food)
}
//抽象方法,子类必须要实现对应方法
abstract run(distance: number): void
}
class Dog extends An {
run(distance: number):void{
console.log('run')
}
}
const dog = new Dog()
dog.eat('骨头')
dog.run(100)
泛型
泛型 声明不指定类型,使用的时候指定类型 定义时不能明确的类型定义成参数
function createArr<T>(length:number,value:T):T[]{
const arr = Array<T>(length).fill(value)
return arr
}
const r = createArr<number>(2,10) //使用的时候指定类型
类型声明
//类型声明 兼容普通js模块 第三方模块没有用ts一般安装类型声明模块
declare function foos(params:string):void