[英]Is it possible to define a function with properties in TypeScript without a type assertion or intermediate?
TypeScript lets you define an interface which is both callable and has properties: TypeScript 允许您定义一个既可调用又具有属性的接口:
interface FnWithProps {
(x: number): number;
a: string;
b: string;
}
Here's one way to create values assignable to this interface:这是创建可分配给此接口的值的一种方法:
function double(x: number) {
return x * x;
}
double.a = 'Hello';
double.b = 'Goodbye';
let f: FnWithProps = double; // ok
If double.a
or double.b
are not set, this triggers an error.如果未设置
double.a
或double.b
则会触发错误。
Is it possible to construct such a value directly, without going through an intermediate or using a type assertion?是否可以直接构造这样的值,而无需通过中间或使用类型断言?
This isn't valid TypeScript and triggers all sorts of errors:这不是有效的 TypeScript,会触发各种错误:
let g: FnWithProps = {
(x: number) => x,
a: 'Hello',
b: 'Goodbye',
};
I think the intermediate solution is probably the best one as it works well for overloads too, but you can also use Object.assign
to get a similar effect :我认为中间解决方案可能是最好的解决方案,因为它也适用于重载,但您也可以使用
Object.assign
来获得类似的效果:
let f: FnWithProps = Object.assign(function double(x: number) {
return x * x;
},{
a : 'Hello',
b : 'Goodbye'
});
Although this does mean we don't get inference for the function params or the properties.尽管这确实意味着我们无法推断函数参数或属性。
If this is a common scenario for you, we can build a utility function to get inference for everything:如果这是您的常见场景,我们可以构建一个实用函数来对所有内容进行推断:
interface FnWithProps {
(x: number): number;
a: string;
b: string;
}
function functionWithProps<T extends (...a: any[]) => any>(fn: (...a: Parameters<T>) => ReturnType<T>, props: Pick<T, keyof T>){
return Object.assign(fn, props);
}
let f = functionWithProps<FnWithProps>(function double(x) { // annotation not necesary
return x * x;
},{
a : 'Hello', // helpful intelisense here
b : 'Goodbye'
});
Edit: Using interface FnWithProps
from original post编辑:使用原始帖子中的
interface FnWithProps
interface FnWithProps {
(x: number): number;
a: number;
b: number;
}
const g:FnWithProps = (()=>{
const obj={
a:2,b:3,
func:function(x:number){ return this.a*x+this.b}
}
return obj.func.bind({a:obj.a,b:obj.b}) as FnWithProps
})()
console.log(g(1))
Demo in typescript playground 打字稿游乐场中的演示
The thing to note here is that this
for the definition of the function is obj
.这里要注意的是,函数定义的
this
是obj
。 That's required to prevent errors with reference to this.这是防止与此相关的错误所必需的。 However, after it is taken out of
obj
, this this
is lost!但是,从
obj
中取出后, this this
就丢失了! So it is replaced by using bind.所以用bind代替了。 (Assign would have worked as well).
(分配也会起作用)。
As an aside, an alternative to using interface
is as follows:顺便说一句,使用
interface
的替代方法如下:
type Fn = (x:number)=>number
type Props = { a: string, b:string}
const g=(function():Fn & Props{
const f=(x:number)=>x*x
f.a='Hello'
f.b='Goodbye'
return f // type checking properly applied here
})()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.