编程语言的类型
动态类型语言
静态类型语言
typescript
特性
优势
类型注解 & 类型推断
基础类型 & 对象类型
联合类型
交叉类型
Partial
枚举
函数注解
数组注解
interface & type
类型断言
类
泛型
泛型约束
声明文件
typescript编译
ts-node 编译执行.ts 文件
tsc
tsconfig
typescript + React
编程语言的类型
动态类型语言
运行期间做数据类型检查 js ruby python
静态类型语言
编译期间类型检查 c c++ java
typescript
==冒号后面的都是类型==
特性
typescript 是 js 的超集
拥有静态类型
需要编译成 js 运行
优势
ts 的静态类型可以在开发过程中,发现潜在问题
更好的编辑器提示
通过静态类型的声明,代码清晰易读
// js中变量是动态类型 可以随时改变类型leta=1;a='str'// ts中是静态类型 改变类型会报错letb=1;b='str'
类型注解 & 类型推断
ts 自动启用类型推断,判断变量类型 如果能分析变量类型不需要类型注解,否则需要
基础类型 & 对象类型
// 基础类型 string number boolean symbol void null undefinedletcount: number;// 对象类型 {} [] function Classconstteacher: {name: string; age: number;} = {name:'jason',age:28,};constnumbers: number[] = [1,2,3];classPerson{}constp: Person =newPerson();constgetTotal:()=>number =()=>{return123;};
联合类型
letmyName:string| number;
交叉类型
将多个类型合并成一个类型
typeNativeButtonProps = BaseButtonProps & ButtonHTMLAttributestypeAnchorButtonProps = BaseButtonProps & AnchorHTMLAttributes
Partial
把一些属性变为可选的
exporttypeButtonProps = Partial
枚举
enum TabTypes {Case='case', Ganged ='ganged',}const[currentTab, setCurrentTab] = useState(TabTypes.Case);if(currentTab === TabTypes.Case) { setCaseSource(insertKeys(res.data)); }else{ setGangedSource(insertKeys(res.data));}
函数注解
函数的入参需要类型注解,返回值如果可以类型推断的话不需要写
// 函数入参及返回值注解 c:可选参数只能放最后functionadd(a: number, b: number, c?: number):number{returna + b;}// 函数表达式constadd2:(x: number, y: number) =>number=(a,b)=>{returna+b}// interface写法interface IFn { (x: number,y: number): number;}constadd2: IFn =(a, b) =>{returna + b;};// type写法type fn =(x: number, y: number) =>number;constadd2: fn =(a, b) =>{returna + b;};// 函数解构的写法functionadd2({ a, b }:{a:number, b: number}):number{returna + b;}add2({a:1,b:2});consttotal = add(1,2);// 无返回值functionsayHello():void{console.log('hello');}// 函数永远不会执行完functionerrorEmitter():never{thrownewError('error');console.log('end');}
数组注解
// 数组注解 能推断出来的不需要注解 直接的赋值的数组ts可以类型推断出来constarr1: number[] = [1,2,3];// 只能是numberconstarr2: (number |string)[] = ['1',2,3];// 可以是number或stringconstarr3: undefined[] = [undefined, undefined];// 只能是undefined// 对象数组constarr4: { name:string; age: number }[] = [{ name:'a', age:18}];// 类型别名 对上面的另一种写法type User = { name:string; age: number };constarr5: User[] = [{ name:'a', age:18}];// 元组 tuple 一个数组的长度固定 元素顺序类型固定constinfo: [string,string, number] = ['andy','male',20];
interface & type
interface是数据的共性的抽象 有自己的属性 只是在开发过程中做语法提示校验的工具 编译后不存在
对对象的形状(shape)的描述
interfacePerson{readonlyname:string;// 只读 该属性再写会报错age?: number;// 可选属性 可有可无[propName: string]: any;// 将来多出的其他属性string类型也是可以的say?():string;// 方法属性 返回值stringsay: ()=>{}}// 接口继承interfaceTeacherextendsPerson{ teach():string;// 自己的属性}
定义函数
// interface 定义函数类型interfaceISayHi{ (word:string):string;}constsay: SayHi = () => {return'hi';};interfaceIModalProps{ visible: boolean;// 是否可见handleClose: () =>void;// 隐藏自身form: any;}
对类(class)进行抽象
interfaceRadio{ switchRadio():void}interfaceBatteryextendsRadio{ checkBatter():void}// 类实现interfaceclassCarimplementsRadio{ switchRadio() { }}classPhoneimplementsBattery{ switchRadio() { } checkBatter() { } }
type 类型别名 只是简单的别名
// 常用于type fnType =(a: string) =>stringtype FooType = string | fnTypetype Person = {name: string; age?: number; };functiongetName(person: Person):void{console.log(person.name);}constsetName =(person: Person, newName: string) =>{ person.name = newName;returnperson;};// 传对象引用和对象字面量的校验结果不一样 前一种无强校验letp = {name:'andy',sex:'male', say() {} };getName(p);getName({name:'andy',sex:'male'});setName({name:'jason'},'andy');
类型断言
联合类型时 ts 只拿到公有的一些方法 使用类型断言联合类型的某一种类型
functiongetLength(input: string | number){// 这里会报错if(input.length){returninput.length }}functiongetLength(input: string | number){// 类型断言 告诉ts我知道他是什么类型conststr = inputasStringif(str.length){returnstr.length }}functiongetLength(input: string | number){// 另一种写法if((input).length){ return (input).length }}
类
ts 给 es6 的类增加了访问修饰符
classPerson{/**
* public 允许在类的内外调用
* private 允许类内不允许子类
* protected 允许类内及继承的子类
* readonly 只能读不能写
* */// 简写constructor(private_name:string,publicage: number){}// 常规写法// public name: string;// constructor(name) {// this.name = name;// }// getter 属性getname(){returnthis._name +'geted'; }// setter 属性setname(value:string){this._name =value}}constp =newPerson('nn',18);console.log(p.name);p.name ='change';console.log(p.name);// ts 实现单例模式classDemo{// 私有静态属性privatestaticinstance: Demo;// 私有constructorprivateconstructor(publicname:string){};// 公共静态方法staticgetInstance(){if(!this.instance){this.instance =newDemo('lee') }returnthis.instance }}// 调用的是同一个instanceconstdemo1 = Demo.getInstance();constdemo2 = Demo.getInstance();console.log(demo1, demo2)
泛型
泛型,泛指的类型, 定义==函数、接口和类==时使用占位符不指定具体类型,使用时才指定,用<>先声明, 声明泛型 T 可以任意命名函数泛型,代表不知道什么类型的同一种类型
函数泛型
// 常规写法functionplus(a: number, b):number{returna + b; }consta = plus// interface写法interface IPlus{ (a: number,b: number): number}constplus:IPlus=(a,b)=>{returna + b;}consta = plus(2,2)// 泛型写法functionjoin(first: T, second: T):T{return`${first}${second}`;}// 可以声明 也可以类型推断join(1,1);join(1,2);functionjoin(first: T, second: P){return`${first}${second}`;}
接口泛型
interface IPlus { (a: T,b: T): T;}constplus: IPlus =(a, b) =>{returna + b;};consta = plus(1,2);constconnet: IPlus =(a, b) =>{returna + b;};constb = connet('hello','ts');
类泛型
classQueue{ private data=[] push(item: T){returnthis.data.push(item) } pop(): T{returnthis.data.pop() }}constq1=newQueue()q1.push(1)q1.push(2)console.log(q1.pop().toFixed());constq2=newQueue()q2.push('ss')console.log(q2.pop().trim())
泛型约束
// 泛型约束 使用extends使泛型满足某些条件interfaceIWithLength{ length: number}functionecho(args: T):T{// 需要一个有length属性的泛型console.log(args.length);returnargs }constres =echo('sss')constres2=echo([1,2,3])// 泛型继承 使用extends扩展类型interfaceIJoin{ name: string;}functionjoin(data:T[]){returndata[0].name;}join([{ name:'sss'}]);
声明文件
第三方库使用时需要声明文件 声明文件以.d.ts 结尾 如:jQuery.d.ts 有了声明文件后项目中就可以使用 jQuery() 提供语法提示且不报错
搜索第三方库的声明文件 TypeSearch 从 npm 安装第三方库的声明文件 npm @types
// jQuery.d.tsdeclarevarjQuery: (selector:string) =>any;
typescript编译
ts-node 编译执行.ts 文件
npminstall -g ts-nodets-node script.ts
tsc
不带任何输入文件的情况下调用 tsc,编译器会从当前目录开始去查找 tsconfig.json 文件,逐级向上搜索父目录。
不带任何输入文件的情况下调用 tsc,且使用命令行参数--project(或-p)指定一个包含 tsconfig.json 文件的目录。
当命令行上指定了输入文件时,tsconfig.json 文件会被忽略。
tsconfig
生成tsconfig.json
tsc--init
使用指定的tsconfig.json编译
// pacage.json"script":{"build-ts":"tsc -p tsconfig.build.json"}
typescript + React
常规写法
importReactfrom'react';interface IHelloProps {name: string}constHello =(props: IHelloProps) =>{return
{`Hello ${props.name}`}
;};exportdefaultHello;使用 react 提供的声明 /node_modules/@types/react/index.d.ts 声明文件