我在玩TypeScript时发现,在可调用函数上应用Omit<T, K>会使其不再可调用:

declare function myCallableFunction(): void;

myCallableFunction(); // valid

type NonOmittedFunction = typeof myCallableFunction;
declare const myNonOmittedFunction: NonOmittedFunction;
myNonOmittedFunction(); // valid

type OmittedFunction = Omit<typeof myCallableFunction, 'foobar'>;
declare const myOmittedFunction: OmittedFunction;
myOmittedFunction(); // This expression is not callable.
                    //  Type 'OmittedFunction' has no call signatures.

为什么会这样?

以下是一个精心设计的示例,您可能希望在其中执行以下操作:

declare type CallCountingFunction = (() => void) & { count: number }
const myFunction: CallCountingFunction = (() => { 
                                            const x = () => {}; 
                                            x.count = 0; 
                                            return x;
                                         })()

myFunction.count; // valid
myFunction() // valid
type OmittedFunction = Omit<CallCountingFunction, 'count'>;
declare const myOmittedFunction: OmittedFunction;
myOmittedFunction(); // This expression is not callable.
                    //  Type 'OmittedFunction' has no call signatures.

Playground

对于涉及重新映射的all种通用实用程序类型(例如Partial<T>Required<T>),这似乎是正确的.

推荐答案

实用程序类型并不是神奇的,它们实际上都是用Typescript编写的,我们可以查看它们.Omit是根据PickExclude定义的.

type Omit<T, K extends keyof any> = Pick<T, Exclude<keyof T, K>>;

没有什么疯狂的,但Pick被定义为

type Pick<T, K extends keyof T> = {
    [P in K]: T[P];
};

因此,Pick<T, K>always,定义为具有索引键的对象类型.这里没有电话签名.很容易将Omit中的think理解为"接受我的类型T并删除一些特定的东西",但在内部,它实际上是"创建一个新的对象类型,该类型具有T的键,减go 一些东西",并且由于调用函数的能力不是对象键,因此它不会被转移.这种类比是错误的,因为从根本上讲,函数并不是真正设计成这样使用的.

Typescript相关问答推荐

在这种情况下,如何获得类型安全函数的返回值?

类型脚本类型字段组合

TypeScript:在作为参数传递给另一个函数的记录中对函数的参数实现类型约束

基于键的值的打字动态类型;种类;

在嵌套属性中使用Required

TS如何不立即将表达式转换为完全不可变?

正交摄影机正在将渲染的场景切成两半

不带其他属性的精确函数返回类型

专用路由组件不能从挂钩推断类型

将对象的属性转换为正确类型和位置的函数参数

TypeScrip-如何自动推断UNION变量的类型

为什么TS2339;TS2339;TS2339:类型A上不存在属性a?

如何将通用接口的键正确设置为接口的键

如何使用警告实现`RecursiveReadonly<;T>;`,如果`T`是原语,则返回`T`而不是`RecursiveReadonly<;T>;`

如何使对象同时具有隐式和显式类型

组件使用forwardRef类型脚本时传递props

将带有额外id属性的Rust struct 展平回TypeScript单个对象,以返回wasm-bindgen函数

使用本机 Promise 覆盖 WinJS Promise 作为 Chrome 扩展内容脚本?

node_modules/@newrelic/native-metrics:命令失败. node_modules/couchbase:命令失败.退出代码:127

如何最好地打破Typescript 尾部递归数量的限制?