[英]How to fix 'Type is missing properties from type' with generic object?
考虑一个导出run
function 的库,如下所示:
runner.ts
export type Parameters = { [key: string]: string };
type runner = (args: Parameters) => void;
export default function run(fn: runner, params: Parameters) {
fn(params);
}
并在一个单独的文件中考虑以下代码: index.ts
import type { Parameters } from "./runner.ts";
import run from "./runner.ts";
type CustomParams = { hello: string };
function logGenericArgs(args: Parameters): void {
console.log(args);
}
function logHelloFromArgs(args: CustomParams): void {
console.log(args.hello);
}
run(logGenericArgs, { abc: "123" });
run(logHelloFromArgs, { hello: "123" }); /* Argument of type '(args: CustomParams) => void' is not assignable to parameter of type 'runner'.
Types of parameters 'args' and 'args' are incompatible.
Property 'hello' is missing in type 'Parameters' but required in type 'CustomParams'. ts(2345)
*/
为什么 TypeScript 抱怨不同的类型,当它们完全兼容时? 据我了解, Parameters
类型是一个通用的 object,带有string
键和string
值; CustomParams
的“hello”键完全符合Parameters
的类型签名。
如何使“runner”库中的代码接受通用的 object 类型,并与其他兼容的类型很好地配合使用?
我不想使用类型unknown
或any
,因为那基本上没用。 我想要run
function 的调用签名来表示args
是 object,但我不想将args
的类型仅限于该特定签名。
我也不想将CustomParams
类型中的hello
键指定为可选的,因为在CustomParams
类型的使用中该键不应该是可选的 - 而且我不想在Parameters
类型中添加键hello
因为它不是必需的“runner”库的每个用例。
TypeScript 不知道params
应该是fn
的参数,但您可以轻松解决这个问题,但添加一个通用参数来关联两者:
type Params = { [key: string]: string };
type runner<P extends Params = Params> = (args: P) => void;
function run<P extends Params>(fn: runner<P>, params: P) {
fn(params);
}
现在,当您调用自定义参数 function 时:
run(logHelloFromArgs, { hello: "123" });
推断为
function run<{
hello: string;
}>(fn: runner<{
hello: string;
}>, params: {
hello: string;
}): void
这就是我们想要的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.