JSDoc
在 JS 使用 TS 检查类型可以使用 JSDoc
如果身边没有会 ts 的人,其实我更建议先用 JSDoc。使用 vscode 或者 webstorm 的时候直接写 JSDoc 就行了,vsc 或 webstorm 会依靠 ts 来提供类型推导和自动完成。这样可以在工作或自己写东西的时候慢慢习惯并且主动去使用类型标注。在使用一段时间后感觉 JSDoc 已经不够用了,满足不了自己的需求了,再开始使用 ts。
1 | // @ts-check |
定义枚举
1 | // @ts-check |
利用TypeScript/框架内置的标准类型
不管是TS语言还是React等框架,均提供了用于开发的标准类型。虽然自己也可以定义类型,不过最好还是使用经过充分测试并且作为开发者之间公共知识的标准类型。
比如使用React时,@types/react提供了一些类型定义,可以使用其中的ComponentProps类型从组件中提取其Props类型。
1 | export type Props = {...} |
使用类型别名而不是Interface
对于刚接触TS的人来说Interface与类型别名看起来没什么区别,现在的应用开发中Interface的使用应该比较少了。
两者均可以用于实现class的interface,并且与类型相关的错误信息也是一致的。在老版本的TS中Interface较易使用,而在目前的版本中类型别名则更为方便。
类型别名中不仅可以使用联合类型(|),使用交叉类型(&)实现类型合并的场景也是很多的。
- 【TypeScript】定义Promise的返回值类型
1
2
3
4
5
6
7
8const main =new Promise<number>(res=>res(1))
function ZnAxios<T>(znAxios: ZnAxios) {
const { method, mockData } = znAxios
return new Promise<T>((resolve, reject) => {
const successCallBack = (res: T) => {
resolve(res)
}
}
或者这么写
1 | function ZnAxios<T>(znAxios: ZnAxios):Promise<T> { |
类型
什么是g.d.ts
- 主要是为了定义全局类名
- .d.ts (d即declare) 为了告诉TS变量的类型
- d.ts”文件用于为 TypeScript 提供有关用 JavaScript 编写的 API 的类型信息。简单讲,就是你可以在 ts 中调用的 js 的声明文件
*.d.ts导入import其它类型导致全局类型失效问题
TS中的特殊字符(?, !, !!)
?: 属性或参数中使用 ?:表示该属性或参数为可选项
1
2
3interface Ia{
a?:number
}!表示类型推断排除null、undefined
1 |
|
InstanceType
构造一个类型,该类型由 中的构造函数的实例类型组成Type。
1 | class C { |
- vue refs 里可以这样使用
1
2
3
4
5
6
7
8
9// child 里 defineExpose({ change, getList })
<Child ref='childVm'/>
// const childVm = ref<ISingleExpose>();
const childVm = ref<InstanceType<typeof Child>>(child)
getChildList(){
unref(childVm).change
}
通过 InstanceType 生成一个构造类型
ts 函数重载
JavaScript本身是个动态语言。 JavaScript里函数根据传入不同的参数而返回不同类型的数据是很常见的。
- 函数重载指 重载函数,形参(类型)不同,实现的功能一样。
- 一般会return 一个变量出来,但是这个变量可以根据函数重载推断出当前return 的类型
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24let suits = ["hearts", "spades", "clubs", "diamonds"];
function pickCard(x: {suit: string; card: number; }[]): number;
function pickCard(x: number): {suit: string; card: number; };
function pickCard(x): any {
// Check to see if we're working with an object/array
// if so, they gave us the deck and we'll pick the card
if (typeof x == "object") {
let pickedCard = Math.floor(Math.random() * x.length);
return pickedCard;
}
// Otherwise just let them pick the card
else if (typeof x == "number") {
let pickedSuit = Math.floor(x / 13);
return { suit: suits[pickedSuit], card: x % 13 };
}
}
let myDeck = [{ suit: "diamonds", card: 2 }, { suit: "spades", card: 10 }, { suit: "hearts", card: 4 }];
let pickedCard1 = myDeck[pickCard(myDeck)];
alert("card: " + pickedCard1.card + " of " + pickedCard1.suit);
let pickedCard2 = pickCard(15);
alert("card: " + pickedCard2.card + " of " + pickedCard2.suit);
这样改变后,重载的pickCard函数在调用的时候会进行正确的类型检查。
为了让编译器能够选择正确的检查类型,它与JavaScript里的处理流程相似。 它查找重载列表,尝试使用第一个重载定义。 如果匹配的话就使用这个。 因此,在定义重载的时候,一定要把最精确的定义放在最前面。
注意,function pickCard(x): any并不是重载列表的一部分,因此这里只有两个重载:一个是接收对象另一个接收数字。 以其它参数调用 pickCard会产生错误。
简单来说,函数重载具有两个特征:名称相同,参数不同(参数类型、个数不同。)所以,函数重载的解释应该是具备不同参数的同名函数。【注意:函数重载是多态的一种体现。】
1 | type MessageType = 'Image' | 'audio' | 'video' | string; |
函数重载签名时候 多个参数不一致时
1 | type MessageType = 'Image' | 'audio' | 'video' | string; |
构造器重载
构造器重载和函数重载使用基本相同,主要区别是:TS类构造器重载签名和实现签名都不要管理返回值(也没有返回值),TS构造器是在对象创建出来之后还没有赋值给对象变量之前执行,一般采用给对象属性赋值
1 | class summation { |
- 本文作者: Littleki
- 本文链接: https:/littleki.gitee.io/2020/04/08/typescript笔记/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!