TS 函数类型
什么是函数类型
ts
// foo本身也是一个标识符,也有自己的类型
function foo(arg: number): number {
return 123
}
const foo = (arg: number) => {
return 123
}
函数类型表达式
ts
// 方案一: 函数类型表达式 function type expression
// 格式: (参数列表) => 返回值
type fnType = (num: number) => number
const fn: fnType = (arg: number): number => {
return 123
}
函数类型表达式案例
ts
type FnType = (num1: number, num2: number) => number
// 2.定义一个函数
const calc = (fn: FnType) => {
const num1 = 123
const num2 = 321
const res = fn(num1, num2)
console.log(res)
}
// 3.传入值返回函数调用
const addFn = (num1: number, num2: number) => {
return num1 + num2
}
// 2.调用函数并向函数内传入一个函数
calc(addFn)
export {}
调用签名
开发中如何选择
- 如果只是描述函数类型本身(函数可以被调用)使用函数类型表达式(function type expression)
- 如果在描述函数作为对象可以被调用,同时也可以有其他属性,使用函数调用签名
ts
// 1.函数类型表达式
type FooType = (num1: number) => number
// 2.函数的调用签名(从对象角度来看待这个函数,也可以有其他属性)
interface IFoo {
name: string
age: number
// 函数可以调用: 函数调用签名
// (参数列表):number
(num1: number): number
}
const foo: IFoo = (num1: number): number => {
return 123
}
foo.name = 'sj'
foo.age = 19
foo(321)
export {}
构造签名(了解)
个构造签名( Construct Signatures ),方法是在调用签名前面加一个 new 关键词
ts
class Person {}
interface ICTORPerson {
new (): Person
}
function factory(fn: ICTORPerson) {
return new fn()
}
factory(Person)
参数的可选类型
ts
// y就是可选参数
// 可选参数类型: number | undefined
function foo(x: number, y?: number) {
if (y != undefined) {
console.log(x, y + 10) // 10 30
}
}
foo(10)
foo(10, 20)
export {}
参数的默认值
ts
// 函数的参数可以有默认值
// 1. 有默认值的情况下,参数类型可以省略
// 2. 有默认值的参数,可以接受一个undefined的值
function foo(x: number, y: number = 100) {
console.log(x, y)
}
foo(10)
foo(10, 20)
剩余参数
从 ES6 开始,JavaScript 也支持剩余参数,剩余参数语法允许我们将一个不定数量的参数放到一个数组中。
ts
function sum(...nums: number[]) {
let value = 0
for (const num of nums) {
value += num
}
return value
}
const result = sum(10, 20, 30)
函数的重载(了解)
ts
// TypeScript 中函数重载写法
// 1. 先编写重载签名
function add(arg1: number, arg2: number): number
function add(arg1: string, arg2: string): string
// 2.编写通用函数实现
function add(arg1: any, arg2: any): any {
return arg1 + arg2
}
add(10, 20)
add('aaa', 'bbb')
函数重载和联合类型选择
案例: 获取一个数据的长度(可以使用联合类型实现尽量用联合类型)
ts
// 1.函数的重载
function getLength(arg: string): number
function getLength(arg: any[]): number
function getLength(arg: any) {
return arg.length
}
getLength('aaaaaa')
getLength(['abc', 'cba', 'nba'])
// 2.联合类型(可以使用联合类型实现尽量用联合类型)
function getLength(arg: string | any[]) {
return arg.length
}
getLength('aaaaaa')
getLength(['abc', 'cba', 'nba'])
// 3.对象类型实现
function getLength(arg: { length: number }) {
return arg.length
}
getLength('aaaaaa')
getLength(['abc', 'cba', 'nba'])
可推导的 this 类型
sh
# 初始化 ts 的配置文件
tsc --init
创建一个 tsconfig.json 文件,并且在其中告知 VSCodethis 必须明确执行(不能是隐式的);
在设置了 noImplicitThis 为 true 时, TypeScript 会根据上下文推导 this,但是在不能正确推导时,就会报错,需要我们明确 的指定 this。
ts
// 1.对象中的函数中的this
const obj = {
name: 'sj',
studying() {
console.log(this.name)
},
}
obj.studying()
// 2.this的指定类型
function foo(this: { name: string }, infos: { name: string }) {
console.log(this) // { name: 'sj' }
console.log(infos.name) // XQ
}
// 第一个参数绑定this 第二个参数是传入的参数
foo.call({ name: 'sj' }, { name: 'XQ' })
this 相关的内置工具
Typescript 提供了一些工具类型来辅助进行常见的类型转换,这些类型全局可用。
ThisParameterType:
- 用于提取一个函数类型 Type 的 this (opens new window)参数类型;
- 如果这个函数类型没有 this 参数返回 unknown;
ts
type FooType = typeof foo
// 1.ThisParameterType: 获取 FooType 类型中的 this 类型
type FooThisType = ThisParameterType<FooType>
function foo(this: { name: string }) {
console.log(this.name)
}
OmitThisParameter:
- 用于移除一个函数类型 Type 的 this 参数类型, 并且返回当前的函数类型
ts
type FooType = typeof foo
// 2.OmitThisParameter: 删除 this 参数类型,剩余的函数类型
type FooThisType = OmitThisParameter<FooType>
function foo(this: { name: string }) {
console.log(this.name)
}
ThisType:
- 这个类型不返回一个转换过的类型,它被用作标记一个上下文的 this 类型。
- 事实上官方文档的不管是解释,还是案例都没有说明出来 ThisType 类型的作用
ts
// 3.ThisType: 用于绑定一个上下文的this类型
interface IState {
name: string
age: number
}
interface IStore {
state: IState
fn?: () => void
}
const store: IStore & ThisType<IState> = {
state: {
name: 'sj',
age: 19,
},
fn: function () {
console.log(this.name)
},
}
store.fn?.call(store.state)
function foo(this: { name: string }) {
console.log(this.name)
}