3 进阶
约 1971 字大约 7 分钟
2025-04-12
索引签名
用于限制键值对的类型
语法:
{[key: keyType]: ValueType }
interface Dictionary {
[key: boolean]: string;
}
模板字面量类型
配合索引签名使用限制参数的命名
interface PropchangeHandler {
[key:`${istring}changed`]:()=> void;
}
Let handlers: PropchangeHandler={
idChanged:()=>{}, //ok
nameChanged:()=>{}, //ok
agechange:()=>{} //err
}
索引签名参数类型不能为字面量类型或泛型类型。 索引签名定义键的类型只能是基础类型和模板字面量类型 record工具类定义键的类型可以是字面量类型以及字面量类型的联合类型
type User1={
[key:"id']: string; //err
}
type User2={
[key: "id" | "name"]: string; //err
}
type User3 = Record<"id", string>; //ok
type User4 = Record<'id' "name",string>; //ok
映射类型
将一个类型映射到当前类型,可在当前类型中修改修饰,可选属性等而不影响原类型,减少代码量 使用+或-前缀来添加或减少修饰符 如果没有前缀的话默认使用+
语法: P:新的映射类型 K:被映射的旧类型 in:类似foreach T:任意类型
{[P in K]:T}
{[P in K]?:T} //将K中的成员全部映射到P中并在P中将这些成员全部设为可选参数
{[P in K]-?:T} //将K中的成员全部映射到P中并在P中将这些成员全部去除可选参数
{readonly[P in K]:T} //将K中的成员全部映射到P中并在P中将这些成员全部添加readonly修饰符
{-readonly[P in K]:T} //将K中的成员全部映射到P中并在P中将这些成员全部去除readonly修饰符
{readonly[P in K]-?:T} ////将K中的成员全部映射到P中并在P中将这些成员全部添加readonly修饰符并全部去除可选参数
条件类型
类型判定也可以使用三目运算符
T extends U ? X : Y
如果U包含T那么返回X,否则返回Y 大写字母都是类型占位符
extends判断是宽窄类型,并不局限于继承 如string | number
和string
就是宽类型包含窄类型,也可以判断成功
关键字
Record
除了索引签名也可以使用record简化键值对的限制
type Record <k extends keyof any,T> ={
[P in K]: T;
}
function calculateSalary(salaryObject:Record<string,number>){
let total=0;
for(const name in salaryObject){
total += salaryObject[name];
}
return total;
}
keyof
获取到对象内部所有成员组成的联合类型
function getAttribute<T,D extends keyof T>(obj: T, key: D): T[D] {
return obj[key];
}
const user ={name:'后盾人',age:18 }
getAttribute(user,'name')
readonly
只读修饰符
type类型别名
类型别名type将一个类型命名一个别名 type和interface的区别
使用类型别名的场景:
- 定义基本类型的别名时,使用 type
- 定义元组类型时,使用 type
- 定义函数类型时,使用 type
- 定义联合类型时,使用 type
- 定义映射类型时,使用 type 使用接口的场景:
- 需要利用接口自动合并特性的时候,使用 interface
- 定义对象类型且无需使用 type 的时候,使用 interface
interface可以类型合并,type不可以
interface
interface User {
name: string;
}
interface User {
id: number;
}
let user:User{
id:666,
name:'tom'
}
type
type User={
name: string;
}
// err:标识符“User”重复
type User={
id:number;
}
类型别名可以为基本类型,联合类型或元组类型定义别名接口不行
type MvNumber = number;
type StringOrNumber = string | number;
type Point=[number,number];
模板字面量类型
type Direction = "left" | "right" | "top" | "bottom'";
type CssPadding =`padding-${Direction}`;
type MarginPadding = `margin-${Direction}`;
多个占位符的联合类型解析为叉积
S1=A|B
S2=C|D
`${S1}-${S2}`=`${A}-${C}` | `${A}-${D}` | `${B}-${C)` | `${B}-${D}`
declare类型声明
declare类型声明,在d.ts中使用,用于声明一个类型让ts编译器识别
- declare:声明
- wx:全局变量名称
- any:变量类型
declare var wx: any;
类型兼容性
两种类型系统:
- StructuralTypeSystem(结构化类型系统)
- NominalTypeSystem(标明类型系统)。
TS 采用的是结构化类型系统,也叫做ducktyping(鸭子类型),类型检查关注的是值所具有的形状。 也就是说,在结构类型系统中,如果两个对象具有相同的形状,则认为它们属于同一类型。
class point{
x:number,
y:number
}
class point2D{
x:number,
y:number
}
class point3D{
x:number,
y:number,
z:number
}
let p1:point=new point2D()
let p2:point=new point3D()
属性多的类型可以赋值给属性少的类型,但属性少的类型不能赋值给属性多的类型 多的属性在赋值时会被舍弃 接口和接口之间,接口与类之间都可以兼容的
函数兼容性 函数之间兼容性比较复杂,需要考虑:1参数个数2参数类型3返回值类型
- 参数个数,参数多的兼容参数少的(或者说,参数少的可以赋值给多的)
type F1 =(a:number)=>void
type F2=(a:number,b:number)=>void
Let f1:F1
Let f2:F2
f2=f1 //ok
f1 =f2 //err
参数类型,相同位置的参数类型要相同(对于原始类型)或兼容(对于对象类型)
返回值类型,只关注返回值类型本身即可: 如果返回值类型是原始类型,此时两个类型要相同 如果返回值类型是对象类型,此时成员多的可以赋值给成员少的
交叉类型和接口继承
交叉类型(&)和接口继承(extends)的对比:
- 相同点:都可以实现对象类型的组合。
- 不同点:两种方式实现类型组合时,对于同名属性之间,处理类型冲突的方式不同。
接口继承之间如果有同名函数签名(形参列表,返回值等)不一致的情况会报错
interface A{
fn: (value: number)=> string
}
interface B extends A{
fn: (value: string)=>string //err
}
交叉类型之间同名函数签名不一致会结合在一起。两个都能调用
interface A{
fn: (value: number))=> string
}
interface B{
fn: (value: string)=>string
}
type C = A & B //ok
泛型工具类
Partial
将一个类型的属性都变为可选的 构造出来的新类型原相同,但所有属性都变为可选的。
Readonly
将一个类型的属性都变为只读的 构造出来的新类型原相同,但所有属性都变为只读的。
Pick
pick工具类型用于挑选出一个类型中需要的字段返回出新的类型
const user={
id:666,
name:'阿宝哥',
address: 'cn'
}
const PickedUser=Pick(user, ["id", "name"]);
PickedUser={
id:666,
name:'阿宝哥'
}
Omit
omit工具类型用于挑选出一个类型中不需要的字段返回新的类型和pick相反
type User = {
id:string;//用户
name:string;//用户名
password:string;//密码
createdAt:Date;//创建时间
updatedAt:Date;//更新时间
}
const a=Omit<User, "id" | "createdAt" | "updateAt">
a={
name:string;
password:string;
}
Record
简化实现统一类型的属性的对象类型
- 第一个参数是交叉类型,其中每个字符串的值都会作为创建类型的属性字段
- 第二个参数是指定所有属性字段的类型
type Recordobj = Record<'a' | 'b' | 'c',string[]>
//相当于
type Recordobj ={
a:string[]
b:string[]
c:string[]
}
文件类型
TS 中有两种文件类型:
- ts文件 implementation(代码实现文件) 既包含类型信息又可执行代码。 可以被编译为js文件,然后,执行代码。 用途:编写程序代码的地方。
- d.ts文件 declaration(类型声明文件)。 只包含类型信息的类型声明文件。 不会生成js文件,仅用于提供类型信息。 用途:为JS提供类型信息。
三斜线指令
三斜线指令相当于es6的import操作,都是导包
/// <reference type="type/typescript" />
贡献者
版权所有
版权归属:PinkDopeyBug