[英]Call Readonly function in Typescript
I'm building an app with an immutable data model and I reached the following dead-end:我正在构建一个具有不可变数据模型的应用程序,但我遇到了以下死胡同:
I have a function that is stored as immutable like in the following example:我有一个存储为不可变的函数,如下例所示:
const f: Readonly<() => void> = () => {};
f();
When calling f
I get the following error:调用
f
出现以下错误:
This expression is not callable.
Type 'Readonly<() => void>' has no call signatures. (2349)
I fail to understand what is transformed by Readonly that produces this effect.我无法理解产生这种效果的 Readonly 转换了什么。
Casting back to mutable doesn't seem to be a solution.转换回 mutable 似乎不是解决方案。 This produces the same error:
这会产生相同的错误:
export type Mutable<T> = {
-readonly [K in keyof T]: T[K];
};
(f as Mutable<typeof f>)();
I'm looking to understand the root cause of this issue, not necessarily look for workarounds, like casting to the exact function type, or not applying Readonly to functions.我希望了解此问题的根本原因,不一定要寻找解决方法,例如强制转换为确切的函数类型,或不对函数应用 Readonly。
You can use Readonly<Function>
to say that the function's properties (eg apply
, bind
, call
...) are read-only, and an intersection type to retain the function's call signature.您可以使用
Readonly<Function>
表示函数的属性(例如apply
、 bind
、 call
...)是只读的,并使用交集类型来保留函数的调用签名。
type ReadonlyFunction<F extends Function> = Readonly<Function> & F;
const f: ReadonlyFunction<() => void> = () => {};
// OK
f();
// Error: Expected 0 arguments, but got 2.
f(1, 2);
// Error: Cannot assign to 'apply' as it is a readonly property.
f.apply = 'foo';
The reason why Readonly<() => void>
doesn't work seems to be that Readonly
is a mapped type , so it maps the properties of the type () => void
, but not the call signature. Readonly<() => void>
不起作用的原因似乎是Readonly
是一种映射类型,因此它映射了类型() => void
的属性,而不是调用签名。
It turns out that the type () => void
has no properties, so eg keyof (() => void)
is never
, and { [K in keyof (() => void)]: any }
is {}
.事实证明,类型
() => void
没有属性,因此例如keyof (() => void)
是never
,而{ [K in keyof (() => void)]: any }
是{}
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.