繁体   English   中英

有没有办法根据 Typescript 中的 function 的另一个参数来缩小参数的类型?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM