这是我参与「第四届青训营 」笔记创作活动的的第11天
👋本文介绍:什么是TS、基本语法(基础数据类型:对象类型、函数类型、数组类型,泛式)
什么是TypeScript?
JS vs TS
JS : 动态类型、弱类型语言
TS : 静态类型、弱类型语言
静态类型
- 可读性增强:基于语法解析TSDoc,ide增强
- 可维护性增强:在编译阶段暴露大部分错误
多人合作的大型项目中,获得更好的稳定性和开发效率
JS的超集
- 包含于兼容JS所有特性,支持共存
- 支持渐进式引入与升级
我们编写好的TS代码最终也会换成JS
基本语法
基础数据类型
原始类型: number/string/boolean/null/undefined/symbol
/*字符串*/
const q:string='string';
/*数字*/
const w:number=1;
/*布尔值*/
const e:boolean=true;
/*nul1*/
constr:null=null;
/*undefined*/
const t:undefined=undefined;
/*symbol*/
const u:symbol = Symbol()
对象类型
const bytedancer:IBytedancer={ //对于一个对象来说类型大多是自定义的,大写I开头表示这是一个类型
jobId:9303245,
name:'Lin',
sex:'man',
age:28,
hobby:'swimming',
}
// 这里用 interface 关键字来声明接口
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,
}
扩:接口和类型
当一个对象类型被多次使用时,有如下两种方式来来描述对象的类型,以达到复用的目的:
- 类型别名,type (不仅可以为对象指定类型,实际上可以为任意类型指定别名)
- 接口,interface (只能为对象指定类型。它可以继承。 )
// 接口的写法-------------
interface IPerson {
name: string,
age: number
}
const user1:IPerson = {
name: 'a',
age: 20
}
// type的写法-------------
type Person = {
name: string,
age: number
}
const user2:Person = {
name: 'b',
age: 20
}
函数类型
function add(x,y){
return x+y;
}
const mult=(x,y)=>x*y;
// 添加类型声明的函数:
function add(x:number,y:number):number{
return x+y;
}
const mult:(x:number,y:number)=>number=(x,y)=>x*y;
// 运用接口定义的函数:
interface IMult {
(x:number,y:number):number;
}
const mult:IMuLt=(x,y)=>x*y;
函数重载
😁函数重载或方法重载是使用相同名称和不同参数数量或类型创建多个方法的一种能力。( 函数提供了多个函数类型定义,从而实现函数的重载 )
type Types = number | string;
// 重载签名(定义函数的形参和返回类型,没有函数体。)
function add(x: number, y: number): number;
function add(x: string, y: string): string;
function add(x: string, y: number): string;
function add(x: number, y: string): string;
//实现签名(具有参数类型和返回类型)
function add(x: Types, y: Types) {
if (typeof x === 'string' || typeof y === 'string') {
return x.toString() + y.toString();
}
return x + y;
}
const result = add('hearts', ' spades');
result.split(' ');
当 TypeScript 编译器处理函数重载时,它会查找重载列表,尝试使用第一个重载定义。 如果匹配的话就使用这个。 因此,在定义重载的时候,一定要把最精确的定义放在最前面。
数组类型
/*最简单的方法是使用「类型 + 方括号」来表示数组:*/
type IArr1=number[];
/*泛型表示*/
type IArr2 = Array< string | number | Record<string,number> >;
/*接口表示*/
interface IArr4{
[key:number]:any;
}
const arr1:IArrl=[1,2,3,4,5,6];
const arr2:IArr2=[1,2,'3','4',{a:1}1];
const arr4:IArr4=['string',()=>null,{},[]];
元祖
😁在 JavaScript 中是没有元组的,元组是 TypeScript 中特有的类型,其工作方式类似于数组 元组最重要的特性是可以限制数组元素的个数和类型,它特别适合用来实现多值返回。
/*元祖表示*/
type IArr3 = [number,number,string,string];
const arr3:IArr3=[1,2,'3','4'];
Typescript补充类
泛型
😁泛型(Generics)是指在定义函数、接口或类的时候,不预先指定具体的类型,而在使用的时候再指定类型的一种特性。
function getRepeatArr(target){
return new Array(100).fill(target);
}
type IGetRepeatArr=(target: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);
/*报错:类型“number”的参数不能赋给类型“string”的参数*/
getStrArr(123);
- 泛型参数默认类型
//类型别名泛型的实现
type IGetRepeatArr<T = number>=(target:T)=>T[];
const getRepeatArr:IGetRepeatArr=target => new Array(100).fill(target);
/*报错:类型“string"的参数不能赋给类型“number”的参数*/
getRepeatArr('123');
补充内容:type关键字
类型别名&类型断言
字符串 / 数字字面量
参考文章: