Typescirpt已经渐渐成为一个前端同学的必备工作技能,但是学习一门语言需要由浅入深,而ts中还支持javascript 语法就更适合我们去边学习边应用。
类型系统
在讲类型系统之前需要提出一对概念强类型 与 弱类型。
我们知道javascript
是一门弱类型语言,语法上可以任意进行隐式类型转换。而强类型,则是规定了数据类型,不可进行隐式类型转换。
静态类型 与 动态类型
-
静态类型
变量声明的时候类型就决定了,并且声明后类型就不允许更改 -
动态类型
运行阶段才明确变量类型,并且变量的类型可以随时发生变化。也就意味着动态类型语言中,变量是没有类型的,而变量存放的值是有类型的。eg:javascript
从类型安全角度: - 强类型
- 弱类型
从类型检查角度: - 静态类型
- 动态类型
强类型 ≠ 静态类型 弱类型 ≠ 动态类型
javascript
是 弱类型 & 动态类型
Flow - 静态类型检查工具
快速上手
yarn add flow-bin
yarn flow init //初始化 flow 配置文件
yarn flow //检查类型错误
// @flow
function sum(a: number, b: number) {
return a + b;
}
console.log(1 + 2)
console.log("1"+ "2")
识别的,所以需要移除那么就需要
yarn flow-remove-types {input} -d {output}
那么就生成了一个 {output}的。
常用插件: flow language support
Typescript
Typescript
是javaScript
的超集
快速上手
yarn init
yarn add typescript --dev
yarn tsc --init
yarn tsc
原始类型
const b: number = 100 //NaN Infinity
const c: boolean = true
const d: void = undefined
const e: null = null
const f:undefined = undefined
// const d: boolean = null 严格模式下不能为 null 非严格模式下可以
const g:symbol = Symbol()
中文错误消息
typescript
有个很人性化的功能,是可以让绝大多数报错信息为中文
const e: null = 1
//yarn tsc --locale zh-CN
//error TS2322: 不能将类型“1”分配给类型“null”。
作用域问题
在同一个作用域下是不被允许同名变量存在的。
(function() {
//命名
})()
// or
export {}
上述两种方式可避免同一作用域下命名相同命名
Object 类型
Object
类型泛指非原始类型
const foo:object = function() {} //[] {}
const obj: {foo: number, bar:string} = {foo:123, bar: "im string"}
数组类型
//基本使用如下
const arr1: Array<number> = [1,1,1]
const arr2: number[] = [1,1,1]
元组类型
const tuple: [number, string] = [1,"1"]
枚举类型
const enum Status { //建议使用常量枚举 编译后会删除该部分
Success = 1, //假如是int的话后面会累加 类似 golang 的 iota
Failed
}
函数类型
//函数
function fn (a: number, b?: number): string {
return "xxxx"
}
//函数表达式
const fn1:(a: number, b?: number)=> string = function (a: number, b?: number): string {
return "xxxx"
}
任意类型
let anyData:any = "any" //避免使用
隐式类型推断
let age = 18 //可推断为number类型
age = "age" //错误
类型断言
const nums = [1,2,3,11]
const res = nums.find(x => x > 0) // res => undefined number
const pow2 = res * res // 报错
const num1 = res as number
const num2 = <number> res // jsx 下不能使用
接口
接口用来约束对象结构,实际运行阶段没有意义
interface Post {
title: string
content: string
}
function printPost(post: Post): void {
console.log(post.title)
console.log(post.content)
}
printPost({
title: "hello ts",
content: "im content"
})
对于接口的成员有些特定的属性
interface Post {
title: string
content: string
subTitle?: string //可选
readonly summary: string //只读
}
const hello: Post = {
title: "hello",
content: "ts",
summary: "summary"
}
// hello.summary = "111" //报错
interface CacheInterface {
[prop: string]: string
}
//动态成员
const c:CacheInterface = {
fff: "123"
}
类
class Person {
public name: string //public 可以省略
private age: number //私有属性 不可以在外部访问
protected sex: string //受保护属性 继承的子类可以访问
constructor(name:string, age:number) {
this.name = name
this.age = age
this.sex = ""
}
sayHi(msg: string):void {
console.log(`im ${this.name}`);
}
}
类与接口
interface eatAndRun {
eat(food: string):void
run(distance: number): void
}
class Person implements eatAndRun {
eat(foo: string):void { }
run(distance: number):void { }
}
class Animal implements eatAndRun {
eat(foo: string):void { }
run(distance: number):void { }
}
抽象类
abstract class Animal{
abstract run(distance: number):void
}
class Dog extends Animal {
run(distance: number): void {
// 实现
}
}
抽象类只能去被继承,不能new一个实例
泛型
function createNumberArray(length: number, value:number): number[] {
const arr = Array<number>(length).fill(value)
return arr
}
function createNumberString(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 = createArray<string>(3,"foo")
类型声明
import {camelCase} from "lodash" //为兼容js语法
declare function camelCase(input: string): string
const res = camelCase("hello typed")
网友评论