文章目录
1、参数类型表达式
- 方案一:函数类型表达式function type expression
- 格式:(参数列表)=>返回值
- 注意:在某些语言中,可能参数名称式可以省略的,但是Typescript是不可以的
type BarType = (num1: number) => number;
const bar: BarType = (age: number): number => {
return 123;
};
2、函数类型参数格式
- TypeScript 对于传入的函数类型的参数个数不进行检测(校验)
- TS对于很多类型的检测报不报错,取决于它的内部规则
- TS版本在不断更新:在进行合理的类型检测的情况,让ts同时更好用(好用和类型检测之间找到一个平衡)
// TypeScript 对于传入的函数类型的参数个数不进行检测(校验)
type CalcType = (num1: number, num2: number) => number;
function calc(calcFn: CalcType) {
calcFn(10, 20);
}
calc(function () {
return 123;
});
// TS对于很多类型的检测报不报错,取决于它的内部规则
interface IPerson {
name: string;
age: number;
}
const p = {
name: "why",
age: 19,
height: 1.88,
address: "广州市",
};
const info: IPerson = p;
3、调用签名(Call Signatures)
- 函数类型表达式并不能支持声明属性
- 如果我们想描述一个带有属性的函数,我们可以在一个对象类型中写一个调用签名(call signature)
- 开发中如何选择:
- 如果只是描述函数本身(函数可以被调用),使用函数类型表达式(Function Type Expressions)
- 如果在描述函数作为对象可以被调用,同时也有其他属性时,使用函数调用签名(Call Signatures)
// 1.函数类型表达式
type BarType = (num1: number) => number;
// 2.函数的调用签名(从对象的角度来看待这个函数,也可以有其他属性)
interface IBar {
name: string;
age: number;
// 函数可以调用:函数调用签名
(num1: number): number;
}
const bar: IBar = (num1: number): number => {
return 123;
};
bar.name = "aaa";
bar.age = 123;
bar(123);
4、构造签名(Construct Signatures)
JavaScript函数也可以使用new操作符调用,当被调用的时候,typescript会认为这是一个构造函数(constructors),因为他们会产生一个新对象
class Person {}
interface ICTRPerson {
new (): Person;
}
function factory(fn: ICTRPerson) {
const f = new fn();
return f;
}
factory(Person);
5、参数可选类型
- 可选参数类型什么?number|undefined联合类型
- 可选类型放在后面
// y是可选参数
// 可选参数类型什么?number|undefined联合类型
function foo(x: number, y?: number) {
if (y !== undefined) {
console.log(y + 20);
}
}
foo(10);
foo(10, 20);
6、参数默认值
- 函数的参数可以有默认值
- 有默认值的情况下,参数的类型注解可以省略
- 有默认值参数,是可以接受一个undefined的值
function foo(x: number, y = 100) {
console.log(y + 10);
}
foo(10);
foo(10, undefined);
foo(10, 55);
7、剩余参数
JavaScript也支持剩余参数,剩余参数预防允许我们将一个不定量的参数放到一个数组中
function foo(...arg: (string | number)[]) {}
foo(123, 321);
foo("abc", 111, "cba");
8、函数重载
- 我们可以区编写不同的重载签名(overload signatures)来表示函数可以以不同的方式进行调用
- 一般是编写两个或者以上的重载签名,再去编写一个通用的函数以及实现
- 根据我们传入的参数类型来决定执行函数体时,到底执行哪一个函数的重载签名
// Typescipt中函数的重载写法
// 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(1, 3);
add("aa", "bbb");
// 通用函数不能被调用
// add({ name: "why" }, "aaa");
// add("111", 111);
9、this明确类型
- 在tsconfig中设置noImplicitThis为true,Typescript会根据上下文推导this,但是在不能正确推导时,就会报错,需要我们明确的指定this
{
"compilerOptions": {
"target": "es2016",
"module": "commonjs",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"noImplicitThis": true,
"skipLibCheck": true
}
}
- 函数的第一个参数类型
- 函数的第一个参数我们可以根据该函数之后被调用的情况,用于声明this的类型(名词必须叫this)
- 在后续调用函数传入参数时,从第二个参数开始传递的,this参数会在编译后被抹除
// 在设置配置选项(编译选项compilerOptions,noImplicitThis设置为true,不允许模糊的this存在)
//1.对象中的函数中的this
const obj = {
name: "why",
studying: function () {
// 默认情况下,this是any类型
console.log(this.name, "studying");
},
};
obj.studying();
// 普通函数 明确指定
function foo(this: { name: string }, info: { name: string }) {
console.log(this, info);
}
foo.call({ name: "why" }, { name: "kobe" });
10、this相关的内置工具
- Typescript提供了一些工具类型来辅助进行常见的类型转换,这些类型全局可用
- ThisParameterType
- 用于提取一个函数类型Type的this(opens new window)参数类型
- 如果这个函数没有this参数返回unknow
- OmitThisParameter
- 用于移除一个函数类型Type的this参数类型,并且返回当前的函数类型
- ThisType:
- 这个类型不返回一个转换过的类型,它被用作标记一个上下文的this类型
function foo(this: { name: string }, info: { name: string }) {
console.log(this, info);
}
type FooType = typeof foo;
// 1.ThisParameterType:获取FooType类型中this的类型
type FooThisType = ThisParameterType<FooType>;
// 2.OmitThisParameter:删除this参数类型,剩余的函数类型
type PureFooType = OmitThisParameter<FooType>;
// 3.ThisType:用于绑定一个上下文的this
interface IState {
name: string;
age: number;
}
interface IStore {
state: IState;
eating: () => void;
running: () => void;
}
const store: IStore & ThisType<IState> = {
state: {
name: "why",
age: 18,
},
eating: function () {
console.log(this.name);
},
running: function () {
console.log(this.age);
},
};
console.log(store.state.name);