type和interface区别
- 相同点
- 都可以用来定义对象,函数等结构
- 功能基本一致,都可以使用泛型
- 不同点
- type是通过引用已经存在的类型,是一种赋值操作,interface定义新的类型
- type可以表示非对象,而interface只能表示对象
- interface可以继承其他类型,type不支持继承
ts中的关键字
- typeof: 用来判断数据类型,返回成员的类型,可以对对象,类,枚举,函数进行类型返回
let obj = {
a: 'a',
b: 2
}
type ObjType = typeof obj
- keyof: 将一个接口对象的全部属性取出来变成联合类型
interface User {
name: string
age: number
action: () => void
}
type UserType = keyof User
let person: UserType = 'name'
let person: UserType = 'age'
let person: UserType = 'aciton'
let person: UserType = 'bc'
- extends:
- in: 可以理解成for in T,就是key遍历keyof T的联合类型中的每一项,T必须是string,number,symbol,联合类型
- infer: 可以在extends + 三目运算的语句中推断待推断的类型,就是从类型中获得类型
type InferType<T> = T extends (infer U)[] ? U : T
type NewType = InferType<number []>
type NewType1 = InferType<string>
- readonly: 将属性变成只读
内置类型
- Partial: 接受一个泛型,返回一个新类型,将泛型中的所有属性都变成可选
type Partial<T> = {
[P in keyof T]?: T[P];
}
- Required: 接收一个泛型,返回一个新类型,将泛型中的所有属性变成必选,与Partial功能完全相反
type Required<T> = {
[P in keyof T]-?: T[P];
}
- Pick: 接受两个泛型(T, U),返回一个新类型,新类型的属性为T中U部分的属性(U一般为:U extends keyof T)
type Pick<T, K extends keyof T> = {
[P in K]: T[P];
};
interface Person {
name: string
age: number
sex: string
}
type Man = Pick<Person, 'name' | 'age'>
- Omit: 接收两个泛型(T, U),返回一个新类型,新类型的属性为T中非U的部分属性,与Pick功能完全相反
type Omit<T, K extends keyof T> = {
[P in Exclude<keyof T, K>]: T[P]
}
interface User {
name: string
age: number
sex: string
}
type Man = Omit<User, 'age'>
- Readonly: 接收一个泛型T,用来将这个泛型中的所有属性都标记为readonly
type Readonly<T> = {
readonly [P in keyof T]: T[P];
}
- Record: 来描述一个对象,这个对象的属性都具有相同的类型
- keyof any返回string number symbol的联合类型
- Record接受两个泛型
type Record<K extends of any, T> = {
[P in K]: T
}
- Exclude:排除
- Extract:取出
- NonNullable:不能为null
- Parameters
- ReturnType
type Fn = (a: number, b: string) => string
type AppendArgument<F extends (...args: any) => any, T> = (
x: T,
...args: Parameters<F>
) => ReturnType<F>
type FinalFn = AppendArgument<Fn, boolean>
- ConstructorParameters:构造参数
- InstanceType:构造返回类型、实例类型
- Uppercase:大写
- Lowercase:小写
- Capitalize:首字母大写
- Uncapitalize:首字母小写
ts中的内置对象当作类型使用
- ECMAScript 的内置对象: Boolean、Number、String、RegExp、Date、Error
- 注意:string是ts的类型,String是构造函数,它们都可以在ts中当作类型使用
- DOM 和 BOM 的内置对象
let body: HTMLElement = document.body;
let allDiv: NodeList = document.querySelectorAll('div');
let div:HTMLElement = document.querySelector('div') as HTMLDivElement
document.addEventListener('click', function (e: MouseEvent) {
});
interface HTMLElementTagNameMap {
"a": HTMLAnchorElement;
"abbr": HTMLElement;
"address": HTMLElement;
"applet": HTMLAppletElement;
"area": HTMLAreaElement;
"article": HTMLElement;
"aside": HTMLElement;
"audio": HTMLAudioElement;
"b": HTMLElement;
"base": HTMLBaseElement;
"bdi": HTMLElement;
"bdo": HTMLElement;
"blockquote": HTMLQuoteElement;
"body": HTMLBodyElement;
"br": HTMLBRElement;
"button": HTMLButtonElement;
"canvas": HTMLCanvasElement;
"caption": HTMLTableCaptionElement;
"cite": HTMLElement;
"code": HTMLElement;
"col": HTMLTableColElement;
"colgroup": HTMLTableColElement;
"data": HTMLDataElement;
"datalist": HTMLDataListElement;
"dd": HTMLElement;
"del": HTMLModElement;
"details": HTMLDetailsElement;
"dfn": HTMLElement;
"dialog": HTMLDialogElement;
"dir": HTMLDirectoryElement;
"div": HTMLDivElement;
"dl": HTMLDListElement;
"dt": HTMLElement;
"em": HTMLElement;
"embed": HTMLEmbedElement;
"fieldset": HTMLFieldSetElement;
"figcaption": HTMLElement;
"figure": HTMLElement;
"font": HTMLFontElement;
"footer": HTMLElement;
"form": HTMLFormElement;
"frame": HTMLFrameElement;
"frameset": HTMLFrameSetElement;
"h1": HTMLHeadingElement;
"h2": HTMLHeadingElement;
"h3": HTMLHeadingElement;
"h4": HTMLHeadingElement;
"h5": HTMLHeadingElement;
"h6": HTMLHeadingElement;
"head": HTMLHeadElement;
"header": HTMLElement;
"hgroup": HTMLElement;
"hr": HTMLHRElement;
"html": HTMLHtmlElement;
"i": HTMLElement;
"iframe": HTMLIFrameElement;
"img": HTMLImageElement;
"input": HTMLInputElement;
"ins": HTMLModElement;
"kbd": HTMLElement;
"label": HTMLLabelElement;
"legend": HTMLLegendElement;
"li": HTMLLIElement;
"link": HTMLLinkElement;
"main": HTMLElement;
"map": HTMLMapElement;
"mark": HTMLElement;
"marquee": HTMLMarqueeElement;
"menu": HTMLMenuElement;
"meta": HTMLMetaElement;
"meter": HTMLMeterElement;
"nav": HTMLElement;
"noscript": HTMLElement;
"object": HTMLObjectElement;
"ol": HTMLOListElement;
"optgroup": HTMLOptGroupElement;
"option": HTMLOptionElement;
"output": HTMLOutputElement;
"p": HTMLParagraphElement;
"param": HTMLParamElement;
"picture": HTMLPictureElement;
"pre": HTMLPreElement;
"progress": HTMLProgressElement;
"q": HTMLQuoteElement;
"rp": HTMLElement;
"rt": HTMLElement;
"ruby": HTMLElement;
"s": HTMLElement;
"samp": HTMLElement;
"script": HTMLScriptElement;
"section": HTMLElement;
"select": HTMLSelectElement;
"slot": HTMLSlotElement;
"small": HTMLElement;
"source": HTMLSourceElement;
"span": HTMLSpanElement;
"strong": HTMLElement;
"style": HTMLStyleElement;
"sub": HTMLElement;
"summary": HTMLElement;
"sup": HTMLElement;
"table": HTMLTableElement;
"tbody": HTMLTableSectionElement;
"td": HTMLTableDataCellElement;
"template": HTMLTemplateElement;
"textarea": HTMLTextAreaElement;
"tfoot": HTMLTableSectionElement;
"th": HTMLTableHeaderCellElement;
"thead": HTMLTableSectionElement;
"time": HTMLTimeElement;
"title": HTMLTitleElement;
"tr": HTMLTableRowElement;
"track": HTMLTrackElement;
"u": HTMLElement;
"ul": HTMLUListElement;
"var": HTMLElement;
"video": HTMLVideoElement;
"wbr": HTMLElement;
}
- 定义Promise: Promise对象不定义类型,ts无法推断
function promise():Promise<number>{
return new Promise<number>((resolve,reject)=>{
resolve(1)
})
}
promise().then(res=>{
console.log(res)
})
实际应用
- Type ‘null’ is not assignable to type ‘number’
定义number时,却赋值了null,定义类型 null | number可以跳过 - 返回Promise对象
定义 Promise满足判断 - 不确定内容的对象
Record<string, any>,string代表对象的key,any代表value - 动态读取对象类型
const textTrim = (key: keyof BaseInterface) => {
commonData.value[key] = (commonData.value[key] as string).replaceAll(' ', '')
}
export const setValueWithDefaultArray = <T extends {}>(arr: T[], defaultArr: T[]): T[] => {
let realArr: T[] = deepClone(arr)
if (arr) {
for (let i = 0; i < arr.length; i++) {
const keyArr: string[] = Object.keys(arr[i])
keyArr.forEach((key: string) => {
if (!realArr[i][key as keyof T]) {
realArr[i][key as keyof T] = defaultArr[0][key as keyof T]
}
})
}
} else {
realArr = deepClone(defaultArr)
}
return realArr
}
- 定义全局类型
1.定义*.d.ts(文件不会被编译成js,只能写类型定义的代码);2.再ts.config.json的include属性值熟组中包含*.d.ts文件(可通配符匹配);3.现在可以全局使用*.d.ts中定义的类型