TypeScript类型声明书写详解(2)

// 第一种:使用<>括号 const convertArrType: string[] = <Array<string>>[].concat(['s']); // 第二种:使用as关键字 const fixArrNever: string[] = ([] as string[]).concat(['s']);

建议使用第二种,因为兼容JSX,第一种官方也不推荐了,虽然它是合法的。

可选属性和默认属性

API中提供的参数很多都有默认值,或者属性可选,怎么书写呢?

class Socket {} // 联合类型 export type SocketType = 'WebSocket' | 'SockJs'; export interface SocketOptions { type: SocketType; protocols?: string | string[]; // 可选 pingMessage: string | (() => string); // 联合类型,可以为string或者函数 pongMessage: string | (() => string); } // 默认值 export function eventHandler = ( evt: CloseEvent | MessageEvent | Event, socket: Socket, type = 'WebSocket' // 默认值 ) => any;

独立函数怎么声明类型

刚开始我也很纠结这个问题,我就是一个独立的函数,怎么声明类型呢?尤其是写事件处理函数的API时。

class Socket {} // 函数的声明方式 export type SocketEventHandler = ( evt: CloseEvent | MessageEvent | Event, socket: Socket ) => any; const eventHandler: SocketEventHandler = (evt, socket) => { } // 可选参数和rest参数 let baz = (x = 1) => {}; let foo = (x: number, y: number) => {}; let bar = (x?: number, y?: number) => {}; let bas = (...args: number[]) => {};

索引属性类型声明

JavaScript中的对象都可以使用字符串索引直接取属性或者调用方法,TypeScript中也有相应的类型声明方法。

type Hello = { hello: 'world'; // key只是一个形式属性名(类似形参一样) [key: string]: string; }; const greeting: Hello = { hi: 'morning' } console.log(greeting['hi'])

动态添加的属性声明

有的时候我们只声明了一个基本的类型结构,然后后续有扩展的情况 ,尤其时二次封装时的options。

interface AxiosOptions {} type AjaxOptions = { axiosOptions: AxiosOptions; // 额外扩展的放入到单独的属性节点下 extraOptions: { [prop: string]: any }; }; type AjaxOptions1 = { axiosOptions?: AxiosOptions; // 不要这样写,因为axiosOptions拼写错误时,ts不会提示 // 尽量把后续扩展的属性,移动到独立的属性节点下 [prop: string]: any }; const ajaxOptions: AjaxOptions1 = { axiosOptions1: {}; // 本意是axiosOptions,但是ts不会提示 }

!的使用

! 标识符告诉ts编译器,声明的变量没有问题,再运行期不会报错。

class BaseSelect extends Vue { options: string[]; // 这里会提示没有在constructor中初始化 created() { this.options = ['inited'] } } class BaseSelect extends Vue { options!: string[]; // 使用 ! 告诉编译器,我知道自己在做什么 created() { this.options = ['inited'] } }

this的使用

对于独立使用的函数,可以声明指定的调用上下文

class Handler { info: string; // 声明指定的this上下文 onClickBad(this: Handler, e: Event) { // oops, used this here. using this callback would crash at runtime this.info = e.message; } } let h = new Handler(); uiElement.addClickListener(h.onClickBad); // error!

声明合并(扩展Vue声明)

来看看使用场景,扩展vue,在vue上添加全局的属性。

// vue的声明在 vue/types/vue.d.ts declare module 'vue/types/vue' { // 相当于Vue.$eventBus interface Vue { $eventBus: Vue; } // 相当于在Vue.prototype.$eventBus interface VueConstructor { $eventBus: Vue; } }

总结

TypeScript声明还有很多高级的用法,目前我也没有用到那么多,在我纠结不会写声明的时候,我就会看看别人的声明文件时怎么写的。

注意:尽量不要把解构和声明写在一起,可读性极差。

class Node { onNodeCheck(checkedKeys: any, { // 解构 checked, checkedNodes, node, event, } : { // 声明 node: any; [key: string]: any; } ) { } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/50e0f4fe947c48c8890deddad632616e.html