typescript学习网址 https://zhongsp.gitbooks.io/typescript-handbook/content/doc/handbook/tsconfig.json.html
------------------------------------------------------------------------------------
1、tsconfig.json 配置文件
https://www.tslang.cn/docs/handbook/compiler-options.html
2、如何编写 TypeScript 声明文件
文章来自:
通过keyof
与typeof
组合可以得到我们想要的结果:
const obj = { name: 'Niko', age: 18 } // 如果是这样的取值,只能写在代码中,不能写在 d.ts 文件中,因为声明文件里边不能存在实际有效的代码 type keys = keyof typeof obj let a: keys = 'name' // pass let b: keys = 'age' // pass let c: keys = 'test' // error
而如果我们想要将一个类型不统一的JSON
修改为统一类型的JSON
也可以使用这种方式:
const obj = { name: 'Niko', age: 18, birthday: new Date() } const infos: Record<keyof typeof obj, string> = { name: '', age: '', birthday: 123, // 出错,提示类型不匹配 test: '', // 提示不是`info`的已知类型 }
获取函数的返回值类型
又比如说我们有一个函数,函数会返回一个JSON
,而我们需要这个JSON
来作为类型。
那么可以通过ReturnType<>
来实现:
function func () { return { name: 'Niko', age: 18 } } type results = ReturnType<typeof func> // 或者也可以拼接 keyof 获取所有的 key type resultKeys = keyof ReturnType<typeof func> // 亦或者可以放在`Object`中作为动态的`key`存在 type infoJson = Record<keyof ReturnType<typeof func>, string>
函数重载
这个概念是在一些强类型语言中才有的,依托于TypeScript
,这也算是一门强类型语言了,所以就会有需要用到这种声明的地方。
例如我们有一个add
函数,它可以接收string
类型的参数进行拼接,也可以接收number
类型的参数进行相加。
需要注意的是,只有在做第三方插件的函数重载定义时能够放到d.ts
文件中,其他环境下建议将函数的定义与实现放在一起(虽说配置paths
也能够实现分开处理,但是那样就失去了对函数创建时的约束)
// index.ts // 上边是声明 function add (arg1: string, arg2: string): string function add (arg1: number, arg2: number): number // 因为我们在下边有具体函数的实现,所以这里并不需要添加 declare 关键字 // 下边是实现 function add (arg1: string | number, arg2: string | number) { // 在实现上我们要注意严格判断两个参数的类型是否相等,而不能简单的写一个 arg1 + arg2 if (typeof arg1 === 'string' && typeof arg2 === 'string') { return arg1 + arg2 } else if (typeof arg1 === 'number' && typeof arg2 === 'number') { return arg1 + arg2 } }
但是这样的函数重载在声明的顺序上就很有讲究了,一定要将精确性高的放在前边:
// 这样是一个错误的示例,因为无论怎样调用,返回值都会是`any`类型 function build(arg: any): any function build(arg: Object): string function build(arg: Date): number
因为TypeScript
在查找到一个函数重载的声明以后就会停止不会继续查找,any
是一个最模糊的范围,而Object
又是包含Date
的,所以我们应该按照顺序从小到大进行排列:
function build(arg: Date): number function build(arg: Object): string function build(arg: any): any // 这样在使用的时候才能得到正确的类型提示 const res1 = build(new Date()) // number const res2 = build(() => { }) // string const res3 = build(true) // any
一些不需要函数重载的场景
函数重载的意义在于能够让你知道传入不同的参数得到不同的结果,如果传入的参数不同,但是得到的结果(类型)却相同,那么这里就不要使用函数重载(没有意义)。
如果函数的返回值类型相同,那么就不需要使用函数重载
Interface
interface
是在TypeScript
中独有的,在JavaScript
并没有interface
一说。
因为interface
只是用来规定实现它的class
对应的行为,没有任何实质的代码,对于脚本语言来说这是一个无效的操作
在语法上与class
并没有什么太大的区别,但是在interface
中只能够进行成员属性的声明,例如function
只能够写具体接收的参数以及返回值的类型,并不能够在interface
中编写具体的函数体,同样的,针对成员属性也不能够直接在interface
中进行赋值: