- 强类型与弱类型
- 静态类型和动态类型
- javaScript 自有类型系统的问题
- Flow静态类型检查方案
- TypeScript语言规范与基本应用。
类型系统
- 强类型与弱类型 (类型安全)
- 静态类型和动态类型 (类型检查) 强类型语言中不允许任意的隐式类型转换, 弱类型语言则允许任意 的数据隐式类型转换。
使用 flow
- 安装flow yarn add flow-bin --dev 变量加:【所需要的类型】
- 代码前@flow.
- yarn flow 移除flow注释。 安装: yarn add flow-remove-types --dev 删除 yarn flow-remove-types . -d dist生成新的文件 使用babel 首先安装: @babel/cli // 核心模块 @babel/core // 核心模块 @babel/preset-flow // 移除flow注释
类型注释
/**
* 类型注释
* @flow
*
*/
function square (n: number) {
return n * n
}
let num: number = 100
function foo():number {
return 100
}
function f00(): void{
// 没有返回值。
}
原始类型
const a: string = 'foobar' const b: number = // NaN // 100 const c: boolean = false const d: null = null const e: void = undefined const f: symbol = Symbol()
数组类型
const arr1: Array // 全部由数字组成的数组。 const arr2: number[] = [1,2,33] // 全部由数字组成的数组。 const foo: [string, number] = ['foo', 100] // 元组 固定类型和长度
对象类型
const obj1: {foo: string, bar: number} = {foo; 'string', bar: 100} // 元组 固定类型
const obj2: {foo?: string, bar: number} = {bar: 100} // ? 代表不是必须 的。
const obj3: {[string]: string} = {} // 健和值都是字符串。
obj3.key1 = 'value'
obj3.key2 = '100'
函数类型
function foo (callback: (string, number) => void) {
callback('string', 100)
}
特殊类型
const a: 'foo' = 'foo'; // 指定自定义类型
const type: 'success' | 'warning' | 'danger' = 'warning'; // 指定指定值
type StringOrNumber = string | number // 变量声明
const foo: StringOrNumber = 'as' || 112; // 只能是这几个
const gender: ? number = null; // number || null || undefined
Miixed ant Any
function passMinxed (value: mixed) {
}
passMinxed('string') // : mixed 任意类型的数据 强类型
passMinxed(100)
function passAny (value: any) {
}
passAny('string') // : any 任意类型的数据 弱类型
passAny(100)
flow 小结
TypeSript 基本使用。
类型使用跟flow一样。 可以跟babel一样可以将es6+, 降低到es3左右版本。可以在任何js运行环境运行。 编译指定文件
yarn add typescript --dev
yarn tsc test.ts
// 就会生成test.js
ts 工程化文件
yarn tsc --init 生成tsconfig.json 打开tsconfig.json
compilerOptions :{
"target": "es2015", // 编译到es2015
"module": "commonjs", //文件输出和引入使用commonjs
"sourceMap": true, // 输出sourceMap
"outDir": "dist", // 编译完输出到这个文件夹
"rootDir": "src", // 把哪个文件编译成js.
"strict": true, // 严格模式开启所以文件的严格模式。 变量为null会报错
"strictNullChecks": true, // 只检查变量不能为空的。
}
// 运行
yarn tsc
// 会生成dist文件夹
void 类型
是为了函数没有返回值来定义的。也可以定义变量 在非严格模式下: void :类型可以是null or ubdefined 在严格模式下: void :类型只能是null
ts配置文件
// tsconfig.json
"lib": ["ES2015","DOM"], // 引入ES2015 and DOM
使用中文的错误消息
yarn tsc --locale zh-CN 强制转换。
ts Object 类型
const foo:object = function () {}
const obj: {foo:number, bar:string} = {
foo: 123,
bar: 'string',
more: 123 // 报错
}
数组类型
const arr1: Array<number> = [1, 2, 3, 3];
const arr2: number[] = [1, 3, 4, 5];
function sum(...args: number[]) {
return args.reduce((prev, current) => prev + current);
}
sum(1,2,3,'ww'); // 报错
元组
const tuple: [number, string] = [18, 'sex']
const [age, sex] = tuple
console.log(age, sex);
枚举
使用const枚举编译完之后会删除调掉定义的枚举。 不使用则不会。编译完会生成一个双向健值对对象。 枚举不设置值会自动从零开始。依次加一。
const enum PostStatus {
Draft = 0,
Unpublished = 1,
Published = 'ccc',
}
const post = {
title: 'Hello TypeScript',
content: 'scxkdcmkdm',
status: PostStatus.Draft
}
// enum PostStatus {
// Draft = 0,
// Unpublished = 1,
// Published = 'ccc',
// }
// const post = {
// title: 'Hello TypeScript',
// content: 'scxkdcmkdm',
// status: PostStatus.Draft
// }
TS 函数类型
// 函数声明
// ?表示可选参数。没有问号说明就是两个参数。不可少,
// 如果参数添加默认值的话这个 参数也是可选状态的
// 可选参数必修放在必选参数之后。
function func1 (a: number, b?: number): string {
return 'func1'
}
// 任意参数写法。
function func1 (...rest: number[]): string {
return 'func1'
}
// 函数表达式
const fun2:(a:number, b: number) => string = function (a:number, b: number): string {
return 'func2'
}
任意类型 any
function stringify (value: any) {
return JSON.stringify(value)
}
变量在声明的时候我们将它赋值就算没有给她类型呢 。它也会根据相应的值推断出他的类型。
TS断言
const nums = [1,34,5,6];
const res = nums.find(i => i > 0);
const num1 = res as number;// 强制指定变量的类型。
// 还可以这么写
const num2 = <number>res // jsx--下会冲突。
ts接口
interface 关键词 设置某一个对象里面每个属性的类型。 readonly: 只读
interface Post {
title: string,
content: string,
subtitle?: string // 可选成员
readonly summary: string // 只读
}
const hello: Post = {
title: '23',
content: '23',
summary: 'asdwdw' // 初始化之后不允许修改。
}
不知道这个对象有多少参数。
interface Cache {
[prop: string]: string
}
const cache: Cache = {}
cache.foo = 'value1'
cache.bar = 'value2'
类
class Person {
public name: string = 'init name' // 公共属性
private age: number // private 标记为私有属性。子类不可访问
// readonly需要在访问修饰符后面。 类型声明的时候使用等号赋值。
protected readonly gender: boolean // protected 受保护的属性 不允许外部访问 只允许子类访问
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
sayHi(msg: string): void {
console.log(`I am ${this.name}, ${msg}`);
console.log(this.age);
}
}
class Student extends Person {
private constructor(name: string, age: number) {
super(name, age);
console.log(this.gender);
}
static created(name: string, age: number) {
return new Student(name, age); //
};
}
Student.created('小红', 18); // 使用它的静态方法来实现new一个新的对象。
const tom = new Person('tom', 18);
console.log(tom.name);
console.log(tom.age); // 属性“age”为私有属性,只能在类“Person”中访问。
console.log(tom.gender); // 属性“gender”受保护,只能在类“Person”及其子类中访问
const jack = new Student(); // 类“Student”的构造函数是私有的,仅可在类声明中访问
TS类与接口
interface EatAndRun {
eat(food: string): void
run(distance: number): void
}
class Person implements EatAndRun {
eat(food: string): void {
console.log(`优雅的进餐: ${food}`);
}
}
class Animal implements EatAndRun {
eat(food: string): void {
console.log(`呼噜噜吃: ${food}`);
}
run(distance: number) {
console.log(`爬行: ${distance}`);
}
}
类“Person”错误实现接口“EatAndRun”。
类型 "Person" 中缺少属性 "run",但类型 "EatAndRun" 中需要该属性。ts(2420)
test.ts(3, 3): 在此处声明了 "run"。
接口需要细化一般一个接口只完成一个功能
interface Eat {
eat(food: string): void
run(distance: number): void
}
interface Run {
eat(food: string): void
run(distance: number): void
}
class Person implements Eat, Run {
eat(food: string): void {
console.log(`优雅的进餐: ${food}`);
}
}
class Animal implements Eat, Run {
eat(food: string): void {
console.log(`呼噜噜吃: ${food}`);
}
run(distance: number) {
console.log(`爬行: ${distance}`);
}
}
抽象类。
abstract class Aniaml { // 抽象类只能被继承不能被实例出对象。
eat(food:string):void {
console.log(`呼噜噜吃:${food}`)
}
abstract run(distance: number):void
}
class Dog extends Aniaml {
run(distance: number): void{
console.log('四角爬行', distance)
}
}
const d = new Dog();
d.eat('嗯洗吗')
d.run(12)
TS泛型
// function createNumberArray(length: number, value: number): number[] {
// const arr = Array<number>(length).fill(value);
// return arr;
// }
// const res = createNumberArray(12, 123);
// 将不确定的类型加上函数旁边加上<T>, 所以不确定的类型让T代表。
function createNumberArray<T>(length: number, value: T): T[] {
const arr = Array<T>(length).fill(value);
return arr;
}
const res = createNumberArray(12, 123);