typescript - 如何检查一个对象是否至少有一条记录?

标签 typescript

我有以下 TS 代码:

type FunctionMap = Record<
  string,
  (...params: any) => any
>

function needsARecordOfFunctions(functions: FunctionMap) {
  /* ... */
}

needsARecordOfFunctions({ myFunc: 'foobar' }); // Type 'string' is not assignable to type '(...params: any) => any'.
needsARecordOfFunctions(); // Expected 1 arguments, but got 0.
needsARecordOfFunctions({ myFunc: () => {} }); // ✅

// This passes but I want it to fail
needsARecordOfFunctions({});

我的问题是,如何让 needsARecordOfFunctions({}) 因上述代码中的类型错误而失败?我想定义一种记录类型,嗯,其中至少定义了一条记录。

Playground

最佳答案

首先,您需要摆脱索引签名,因为索引签名有助于类型的形状:

keyof { [x:string]: any }; // string | number

Credit对于通用实用程序类型转到 Mihail ,我只适配了TS 4.1+。它的要点是如果stringkeyof T 的子类型, 这意味着该类型有一个 string索引签名(检查 number 得到我们的数字签名):

type RemoveIndex<T> = {
  [ P in keyof T as string extends P ? never : number extends P ? never : P ] : T[P]
};

接下来,您需要让编译器推断传递给要处理的参数的参数类型。因此,您需要一个通用函数签名,在您的情况下,单个参数被限制为 FunctionMap .

最后,您必须确保推断类型通过“无空对象”约束。这可以通过应用 keyof {} 的观察来实现是never (有关详细信息,请参阅 this Q&A)。因此有条件的 keyof RemoveIndex<T> extends never ? never : T确保此类空对象类型不可分配(有关类似示例,请参见 this Q&A):

function needsARecordOfFunctions<T extends FunctionMap>(functions: keyof RemoveIndex<T> extends never ? never : T) { /* ... */ }

将所有这些结合在一起:

needsARecordOfFunctions({ myFunc: 'foobar' }); // Type 'string' is not assignable to type 'never'
needsARecordOfFunctions(); // Expected 1 arguments, but got 0.
needsARecordOfFunctions({ myFunc: () => {}, func2: () => 42 }); // ✅
needsARecordOfFunctions({}); // error, expected

Playground

关于typescript - 如何检查一个对象是否至少有一条记录?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67939884/

相关文章:

typescript - 获取函数的返回类型

typescript - ES6/ typescript 导入 : import * and names on a single line

reactjs - React Antd 模态属性 'children' 在类型 'IntrinsicAttributes & ModalProps' 上不存在

angularjs - 使用 Angular2 和 TypeScript 将 http 功能移动到它自己的服务中

javascript - 如何将 Node 应用程序逐渐从 javascript 迁移到 Typescript

javascript - 模板中的 Angular 2 主题标签是什么意思?

Angular 6 - 使用 ng-content 时样式不起作用

Jquery Promises Chaining + Typescript = 类型不匹配

typescript - TS2322 : Type  'File'  is not assignable to type  'typeof File'

angular - 子组件不更新父路由更改