![](/img/trans.png)
[英]Narrow the function return type based on the return type of a function passed as an argument
[英]Is there a way to narrow the type of an argument based on another argument to a function in Typescript?
我正在尝试为一些过滤器类型的操作创建一个迷你 DSL,并为它编写一些辅助方法。
说我有 function
const equals = (left, right) => {}
需要键入此函数,以便left
值是 object 上的字段, right
值是 object 类型的值。
如果我这样做const equals = <T> (left: keyof T, right: T[keyof T]) => {}
,我会接近但right
会缩小到T
上可用的类型,而不仅仅是left
的类型。
可以通过以下方式实现所需的行为:
const equals = <T, F extends keyof T>(left: F, right: T[F])
但这需要两个通用参数,这会破坏我围绕此 function 的代码的类型推断链。 理想情况下,我想根据第一个参数键入第二个参数。 这可能吗?
谢谢
您可能正在寻找以下几行的内容。 解决方案是将一些类型验证逻辑移至智能构造函数。
// model
type PickPropertiesOfType<T, A> = Pick<
A,
{
[K in keyof A]: A[K] extends T ? K : never;
}[keyof A]
>;
export type Filter<A> =
| { kind: "Equals"; field: string & keyof A; value: A[string & keyof A] }
| { kind: "EqualsField"; field: string & keyof A; value: string & keyof A };
export const equalsOtherField = <A, K extends string & keyof PickPropertiesOfType<A[K], A>>(
field: string & K,
value: string & keyof PickPropertiesOfType<A[K], A>
): Filter<A> => ({
kind: "EqualsField",
field,
value: value,
});
export const equals = <A, K extends string & keyof A>(field: string & K, value: A[K]): Filter<A> => ({
kind: "Equals",
field,
value: value,
});
// example
type ExampleEntity = {
author: string;
publisher: string;
year: number;
}
const exampleEntity: ExampleEntity = {
author: "Foo",
publisher: "Foobar",
year: 2000
}
const filterArr: Filter<ExampleEntity>[] = [
equals("author", "Bar"),
equalsOtherField("author", "publisher"),
];
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.