外观
外观
怡然
2491字约8分钟
2024-10-30
TypeScript
自己会推断出来。function hello(txt: string): void {
console.log("hello " + txt);
}
// 参数txt的类型(string)
// void类型表示没有返回值
// 写法一
const hello = function (txt: string) {
console.log("hello " + txt);
};
// 写法二
const hello: (txt: string) => void = function (txt) { //函数的参数要放在圆括号里面,不放会报错
//类型里面的参数名(本例是txt)是必须的
console.log("hello " + txt);
};
type MyFunc = (txt: string) => void;
const hello: MyFunc = function (txt) {
console.log("hello " + txt);
};
function add(x: number, y: number) {
return x + y;
}
const myAdd: typeof add = function (x, y) {
return x + y;
};
// {
// (参数列表): 返回值
// }
let add: {
(x: number, y: number): number;
};
add = function (x, y) {
return x + y;
};
function f(x: number) {
console.log(x);
}
f.version = "1.0";
// 可写成以下模式
let foo: {
(x: number): void;
version: string;
} = f;
Interface
来声明interface myfn {
(a: number, b: number): number;
}
var add: myfn = (a, b) => a + b;
TypeScript
提供 Function
类型表示函数,任何函数都属于这个类型。Function
类型的函数可以接受任意数量的参数,每个参数的类型都是any
,返回值的类型也是any
,代表没有任何约束,所以不建议使用这个类型,给出函数详细的类型声明会更好。function doSomething(f: Function) {
return f(1, 2, 3);
}
const repeat = (str: string, times: number): string => str.repeat(times);
function greet(fn: (a: string) => void): void {
fn("world");
}
type Person = { name: string };
const people = ["alice", "bob", "jan"].map((name): Person => ({ name }));
Person
是一个类型别名,代表一个对象,该对象有属性name
。变量people
是数组的map()
方法的返回值。map()
方法的参数是一个箭头函数(name):Person => ({name})
,该箭头函数的参数name
的类型省略了,因为可以从map()
的类型定义推断出来,箭头函数的返回值类型为Person
。相应地,变量people
的类型是Person[]
。({name})
,表示返回一个对象,该对象有一个属性name
,它的属性值为变量name
的值。这里的圆括号是必须的,否则(name):Person => {name}
的大括号表示函数体,即函数体内有一行语句name
,同时由于没有return
语句,这个函数不会返回任何值。|undefined
,它有可能为undefined
。undefined
的参数,就不能省略。function f(x?: number) { //实际上是number|undefined
// ...
}
f(); // 正确
f(10); // 正确
f(undefined); // 正确
undefined
。let myFunc: (a: number | undefined, b: number) => number;
undefined
。let myFunc: (a: number, b?: number) => number;
myFunc = function (x, y) {
if (y === undefined) {
return x;
}
return x + y;
};
function createPoint(x: number = 0, y: number = 0): [number, number] {
return [x, y];
}
createPoint(); // [0, 0]
// 报错
function f(x?: number = 0) {
// ...
}
undefined
,也会触发默认值。function f(x = 456) {
return x;
}
f2(undefined); // 456
function f([x, y]: [number, number]) {
// ...
}
function sum({ a, b, c }: { a: number; b: number; c: number }) {
console.log(a + b + c);
}
// 参数结构可以结合类型别名(type 命令)一起使用
type ABC = { a: number; b: number; c: number };
function sum({ a, b, c }: ABC) {
console.log(a + b + c);
}
rest
参数rest
参数表示函数剩余的所有参数,它可以是数组(剩余参数类型相同),也可能是元组(剩余参数类型不同)。// rest 参数为数组
function joinNumbers(...nums: number[]) {
// ...
}
// rest 参数为元组 元组需要声明每一个剩余参数的类型
function f(...args: [boolean, number]) {
// ...
}
function f(...args: [boolean, string?]) {}
rest
参数可以嵌套。rest
参数可以与变量解构结合使用。// 嵌套
function f(...args: [boolean, ...string[]]) {
// ...
}
// 解构
function repeat(...[str, times]: [string, number]): string {
return str.repeat(times);
}
// 等同于
function repeat(str: string, times: number): string {
return str.repeat(times);
}
readonly
只读参数readonly
关键字,表示这是只读参数。function arraySum(arr: readonly number[]) {
// ...
arr[0] = 0; // 报错
}
void
类型void
类型表示函数没有返回值。void
类型允许返回undefined
或null
。strictNullChecks
编译选项,那么 void
类型只允许返回undefined
。如果返回null
,就会报错。这是因为 JavaScript
规定,如果函数没有返回值,就等同于返回undefined
。void
类型的函数,那么并不代表不能赋值为有返回值的函数。该变量、对象方法和函数参数可以接受返回任意值的函数,这时并不会报错。type voidFunc = () => void;
const f: voidFunc = () => {
return 123;
};
// TypeScript 认为,这里的 void 类型只是表示该函数的返回值没有利用价值,或者说不应该使用该函数的返回值。
// 只要不用到这里的返回值,就不会报错。
// 如果后面使用了这个函数的返回值,就违反了约定,则会报错。
type voidFunc = () => void;
const f: voidFunc = () => {
return 123;
};
f() * 2; // 报错
push()
有返回值,表示新插入的元素在数组里面的位置。但是,对于forEach()
方法来说,这个返回值是没有作用的,根本用不到,所以 TypeScript
不会报错。const src = [1, 2, 3];
const ret = [];
src.forEach((el) => ret.push(el));
never
类型never
类型表示肯定不会出现的值,他用在函数的返回值,就表示某个函数肯定不会返回值,即函数不会正常执行结束。function fail(msg: string): never {
throw new Error(msg);
}
const sing = function (): never {
while (true) {
console.log("sing");
}
};
注意
never
类型不同于void
类型。前者表示函数没有执行结束,不可能有返回值;后者表示函数正常执行结束,但是不返回值,或者说返回undefined
。
function hello(txt: string) {
type message = string;
let newTxt: message = "hello " + txt;
return newTxt;
}
const newTxt: message = hello("world"); // 报错
(someValue: number) => (multiplier: number) => someValue * multiplier;
reverse("abc"); // 'cba'
reverse([1, 2, 3]); // [3, 2, 1]
// reverse函数内部有处理字符串和数组的两套逻辑,根据参数类型的不同,分别执行对应的逻辑。
TypeScript
对于“函数重载”的类型声明方法是,逐一定义每一种情况的类型。function reverse(str: string): string;
function reverse(arr: any[]): any[];
function reverse(stringOrArray: string | any[]): string | any[] {
if (typeof stringOrArray === "string")
return stringOrArray.split("").reverse().join("");
else return stringOrArray.slice().reverse();
}
TypeScript
是按照顺序进行检查的,一旦发现符合某个类型声明,就不再往下检查了,所以类型最宽的声明应该放在最后面,防止覆盖其他类型声明。function f(x: any): number;
function f(x: string): 0 | 1;
function f(x: any): any {
// ...
}
const a: 0 | 1 = f("hi"); // 报错
new
命令调用。const d = new Date();
new
命令。class Animal {
numLegs: number = 4;
}
type AnimalConstructor = new () => Animal;
function create(c: AnimalConstructor): Animal {
return new c();
}
const a = create(Animal);
type F = {
new (s: string): object;
};
Date()
。这时,类型声明可以写成下面这样。type F = {
new (s: string): object;
(n?: number): number;
};