简单介绍
JavaScript是动态类型的弱类型语言
TypeScript是静态类型的弱类型语言
静态类型的优势
- 可读性增强
- 可维护性增强:编译阶段暴露大部分错误
基础语法
基础类型
在定义变量时,在变量后加上:变量名称
const q: string = 'string'
const w: number = 1
const e: boolean = true
const r: null = null
const t: undifined = undifined
对象类型
const bytedancer:IBytedancer = {
jobId:9303245,
name: 'Lin',
sex: 'man',
age: 28,
hobby: 'swimming',
}
interface IBytedancer {
/* 只读属性:约束属性不可在对象初始化外赋值 */
readonly jobId: number;
name: string;
sex: 'man'|'woman'|'other';
age: number;
/* 可选属性:定义该属性可以不存在 */
hobby?: string;
/* 任意属性:约束所有对象属性都必须是该属性的子类型 */
[key:string]: any;
}
/*报错:无法分配到"jobId",因为它是只读属性*/
bytedancer.jobId 12345;
/*成功:任意属性标注下可以添加任意属性*/
bytedancer.plateform = 'data';
/*报错:缺少属性"name",hobby可缺省*/
const bytedancer2: IBytedancer {
jobId: 89757,
sex: 'woman',
age: 18,
}
函数类型
函数类型也是直接在定义的函数名称后面指明:函数类型
const mult: (x: number, y: number) => number = (x, y) => x * y;
但是函数类型的声明显然比较冗长,我们同样可以用interface的方式把先定义函数类型,然后在定义函数
interface IMult {
(x: number, y: number): number
}
const mult: IMult = (x, y) => x * y
以上两种定义函数的方式是等价的
函数重载
/*对getDate函数进行重载,timestamp为可缺省参数*/
function getDate(type: 'string', timestamp?: string): string;
interface IGetDate {
(type: 'string', timestamp?: string): string
(type: 'date', timestamp?: string): Date
(type: 'string' | 'date', timestamp?: string): Date | string
}
/*不能将类型“(type:any,timestamp:any)=>string |Date”"分配给类型“IGetDate”。 不能将类型“string|Date”分配给类型“string”。 不能将类型“Date”分配给类型“string'”。ts(2322))*/
const getDate2: IGetDate = (type, timestamp) => {
const date = new Date(timestamp)
return type === 'string' ? date.toLocaleString() : date
}
数组类型
/*「类型+方括号」表示*/
type IArr1 = number[];
/* 泛型表示 */
type IArr2 = Array<string | number | Record<string,number>>;
/*元祖表示*/
type IArr3 = [number,number,string,string];
/*接口表示*/
interface IArr4 {
[key:number]:any;
}
const arr1:IArr1=[1,2,3,4,5,6];
const arr2:IArr2=[1,2,'3','4',{a:1}];
const arr3:IArr3 = [1,2,'3,'4];
const arr4:IArr4 = ['string',()=>null,{},[]]
TypeScript补充类型
/*空类型,表示无赋值*/
type IEmptyFunction = () => void;
/*任意类型,是所有类型的子类型*/
type IAnyType = any;
/*枚举类型:支持枚举值到枚举名的正、反向映射*/
enum EnumExample {
add='+',
mult = '*'
}
EnumExample[add'] === '+'
EnumExample['+'] === 'add'
enum ECorlor { Mon,Tue,Wed,Thu,Fri,Sat,Sun }
ECorlor['Mon']===0;
ECorlor[0]==='Mon';
TypeScript泛型
function getRepeatArr(target) {
return new Array(100).fill(target);
}
我们希望这里的target可以是任意的类型,我们传入什么类型,函数就返回什么类型的数组
如果这里像这样使用any type IGetRepeatArr (target:any)=>any[];
可以编译通过,但是并不符合我们的需求。因为这里传入的是any类型,返回的是any类型的数组,并不是我们所说的任何一个指定的类型。所以这里要用泛型。
/* 不预先指定具体的类型,而在使用的时候再指定类型的一种特性 */
type IGetRepeatArrR = <T>(target:T)=>T[]
/*泛型接口&多泛型*/
interface IX<T,U> {
key:T;
val:U;
}
/*泛型类*/
class IMan<T> {
instance:T;
}
/*泛型别名*/
type ITypeArr<T>Array<T>;
/*泛型约束:限制泛型必须符合字符串*/
type IGetRepeatStringArr = <T extends string>(target:T)=T[];
const getstrArr:IGetRepeatStringArr = target =new Array(100).fill(target);
/*报错:类型“numbe r”的参数不能赋给类型“string”的参数*/
getstrArr(123);
/*泛型参数默认类型*/
type IGetRepeatArr<T number>(target:T)=>T[];
const getRepeatArr:IGetRepeatArr target =new Array(100).fill(target);
/*报错:类型“string”的参数不能赋给类型“numbe r"的参数*/
getRepeatArr('123');
类型别名和类型断言
/*通过type关键字定义了IObjArr的别名类型*/
type IObjArr = Array<{
key:string;
[objKey:string]:any;
}>
function keyBy<T extends IObjArr>(objArr:Array<T>){
/*未指定类型时,result类型为{}*/
const result = objArr.reduce((res,val,key)=>
res[key]val;
return res;
},{});
/*通过as关键字,断言result类型为正确类型*/
return result as Record<string,T>;
}
字符串/数字 字面量
允许指定字符串/数字必须的固定值
/*IDomTag.必须为htmL、body、div、span中的其一*/
type IDomTag 'html'|'body'|'div'|'span';
/*IOddNumber必须为1、3、5、7、9中的其一*/
type IOddNumber 1|3|5|7|9;
高级类型
联合/交叉类型
- 联合类型:A|B;联合类型表示一个值可以是几种类型之一
- 交叉类型:A&B;多种类型叠加到一起成为一种类型,它包含了所需的所有类型的特性