我有以下 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({})
因上述代码中的类型错误而失败?我想定义一种记录类型,嗯,其中至少定义了一条记录。
最佳答案
首先,您需要摆脱索引签名,因为索引签名有助于类型的形状:
keyof { [x:string]: any }; // string | number
Credit对于通用实用程序类型转到 Mihail ,我只适配了TS 4.1+。它的要点是如果string
是 keyof 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
关于typescript - 如何检查一个对象是否至少有一条记录?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67939884/