函数的参数指定Typescript中的几个函数类型
这是我的代码,我不知道怎么写!我觉得非常复杂!!请帮帮我,谢谢函数的参数指定Typescript中的几个函数类型,typescript,Typescript,这是我的代码,我不知道怎么写!我觉得非常复杂!!请帮帮我,谢谢 interface IMethods { aa(): number; bb(): boolean; cc(): string; } const methods: IMethods = { aa: (): number => { return 0; }, bb: (): boolean => { return false; }, cc: (): string =>
interface IMethods {
aa(): number;
bb(): boolean;
cc(): string;
}
const methods: IMethods = {
aa: (): number => {
return 0;
},
bb: (): boolean => {
return false;
},
cc: (): string => {
return '';
},
};
// what type??
function Demo(func: ???) {
func();
}
Demo(methods.aa); // expect true
Demo(function other() {}); // expect error!!!!
我想了一个办法,像这样
function Demo(func: IMethods[keyof IMethods]) {
func();
}
我不知道有没有更好的办法 听起来你想把方法中的某些函数视为特殊函数,让它们的类型表明它们不仅仅是函数,Typescript允许我们这样做。您想要什么的基本思想是以Haskell中的关键字newtype命名。Typescript为我们提供了几种实现这种模式的方法,我特别喜欢使用 首先,我们需要一个不可能被人意外实现的类型。如果我们制作了一个界面,那么无论我们在里面放了什么,用户仍然有可能意外地满足它。因此,我们将创建一个具有私有成员的类,这将强制类型为。实际上,这意味着只有类的实际实例被视为类型的成员,而不是碰巧具有相同形状的其他对象
class NominalClass {
private _tag: object;
}
现在我们要对类型系统撒谎,以得到我们想要的保证。类型=>T太笼统了;它将允许任何功能,包括您想要禁止的功能。所以我们要做一个新的类型,有效地说我基本上是一个函数,但我很特别。在Haskell或Scala中,我们可以将函数包装为一个新类型,但Typescript可以做得更好:交叉类型
type FromIMethods<T> = NominalClass & (() => T);
就像我说的,它们仍然是函数,所以我们仍然可以调用它们。我们只是给它们增加了一点结构。现在我们对类型系统撒谎。我们说我有办法把一个普通函数变成一个FromIMethods,这当然是不可能的,但是Typescript不在乎
function toIMethod<T>(mthd: (() => T)): FromIMethods<T> {
return mthd as FromIMethods<T>;
}
我们编写了一个演示代码,以获取FromIMethods并返回一个T
现在,用户不可能意外地将普通函数传递给Demo;它们必须传递来自方法的函数。当然,恶意用户总是有可能通过强制转换来规避您的类型安全性
Demo((function() {}) as FromIMethods<void>)
但是对于任何类型和函数,在Typescript中都是如此,所以不值得担心。ohhh,谢谢!!!
const methods: IMethods = {
aa: toIMethod((): number => {
return 0;
}),
bb: toIMethod((): boolean => {
return false;
}),
cc: toIMethod((): string => {
return '';
}),
};
function Demo<T>(func: FromIMethods<T>): T {
return func();
}
Demo(methods.aa) // True
Demo(function() {}) // Error
Demo((function() {}) as FromIMethods<void>)