function,翻译为“函数”还是“方法”?我习惯叫“方法”,当然这个不是重点,你说叫啥就叫啥。
普通函数
- js 函数
function fun(name) {
alert('普通函数' + name)
}
- ts函数
function fun(name: string): void {
alert('普通函数')
}
js里的函数很随意,拿过来写就好了,参数随意,返回值随意。
但是 ts 里的函数,需要做各种声明。首先要明确参数类型、数量,然后明确返回类型。
Typescript 是类型约束,并不是“阉割”js的灵活性,所以,ts的函数就出现了各种形式的约束。
参数类型和返回类型
/*Person 的说明*/
interface Person {
/*姓名*/
name: string,
/*年龄*/
age: number
}
function fun (perosn: Person): Person {
person.age ++
return person
}
这样可以通过 interface明确参数类型和返回类型,返回类型可以和参数类型一致,也可以不一致。
明确参数类型的好处很明显,可以明确参数的结构和类型。以前使用别人的js函数,最头痛的就是,不知道参数要做成什么样子的,只能看文档,如果文档没有及时更新的话,就懵逼了。
现在可以看参数类型 的 interface 的定义,如果 interface 用jsDoc的注释的话,还可以得到说明提示,写起来就非常方便了。
可选参数
function buildName(firstName: string, lastName?: string) {
// ...
}
lastName 这个参数可以不传递,可选参数必须写在后面,不能写在前面。
默认参数
function buildName(lastName = "Smith", firstName: string) {
// ...
}
可以给参数设置一个默认值,可以不用写在后面,调用的时候,需要传入 undefined 来占位。
剩余参数
function buildName(firstName: string, ...restOfName: string[]) {
return firstName + " " + restOfName.join(" ");
}
let employeeName = buildName("Joseph", "Samuel", "Lucas", "MacKinzie");
普通 js 的函数里面可以用 arguments 来获取参数的集合,那么 ts 怎么实现呢?
剩余参数会被当做个数不限的可选参数。 可以一个都没有,同样也可以有任意个。 编译器创建参数数组,名字是你在省略号(...)后面给定的名字,你可以在函数体内使用这个数组。
泛型
function identity<T>(arg: T): T {
return arg;
}
这是一个简单的例子,参数是什么类型的,函数就返回什么类型。
看看vue的 ref :
import { ref } from 'vue'
import type { Ref } from 'vue'
const year: Ref<string | number> = ref('2020')
year.value = 2020 // 成功!
// 或者 在调用 ref() 时传入一个泛型参数
const year = ref<string | number>('2020')
泛型的约束
其实,原生 js 就是一个没有任何类型约束的“大号泛型”。
而TS的泛型,就是要给这种 “随意” 加上一个范围限制。使用 extends 实现范围约束。
/** 只能传入字符串类型的数组 */
function foo<T extends Array<string>>(arg: T): T {
console.log(arg.length)
return arg
}
foo(['2','3','4']) // 正确
foo(['2','3','4', 2]) // 错误:(2)不能将类型“number”分配给类型“string”
foo<Array<number>>(['2','3','4'])
// (Array<number>)错误:类型“number[]”不满足约束“string[]”。
// 不能将类型“number”分配给类型“string”
所以,我觉得,带上约束才是真谛,否则,直接 any 好了。。。
网友评论