【问题标题】:Issues with handling union vs intersection Typescript处理联合与交叉打字稿的问题
【发布时间】:2021-02-08 05:24:13
【问题描述】:

我正在尝试用几个方法构建一个接口,然后根据传入的数据作为该对象的键之一调用这些方法。

这是我的类型:

type LogicalFunction<T> = (args: T) => string;

export interface LogicalFunctions
  extends Record<string, (args: QueryObject & QueryObject[]) => string> {
  $not: LogicalFunction<QueryObject>;
  $and: LogicalFunction<QueryObject[]>;
  $or: LogicalFunction<QueryObject[]>;
}

这是我正在使用的对象:

export const logicalFunctions: LogicalFunctions = {
  $not: (expression: QueryObject) => `NOT(${queryBuilder(expression)})`,
  $and: (args: QueryObject[]) => `AND(${queryBuilder(args)})`,
  $or: (args: QueryObject[]) => `OR(${queryBuilder(args)})`,
};

最后,我实际调用函数的地方:

if (
  key in logicalFunctions 
  && (isQueryObject(val) || (val instanceof Array && val.every(v => isQueryObject(v))))
) { logicalFunctions[key](val); }

但正如我所写,我从 Typescript 编译器收到以下错误:

Argument of type 'QueryObject | QueryObject[]' is not assignable to parameter of type 'QueryObject &amp; QueryObject[]'

我不确定我是否只是用某种反模式编写了这个,或者我只是遗漏了一些东西。任何帮助或指导将不胜感激:)

【问题讨论】:

  • 请提供一个完整的最小示例。我尝试在这里复制它没有成功:tsplay.dev/8w8O4W。您可以编辑它并帮助说明问题。同时,我认为你应该改用(args: QueryObject | QueryObject[]) =&gt; string这个

标签: typescript compiler-errors static-typing union-types


【解决方案1】:

QueryObject &amp; QueryObject[] 表示参数必须同时是 QueryObjectQueryObjects 的数组。这很可能是不可能的。

QueryObject | QueryObject[] 表示参数是QueryObjectQueryObjects 的数组。这可能就是你想要的。

在这个例子中viewable in Typescript Playground

type T = number | T[]
const t0:T&T[] = [2]   // OK
const t1:T&T[] = 2     // NG

type U = number
const u0:U&U[] = [2]   // NG
const u1:U&U[] = 2     // NG

const uu0:U|U[] = [2]   // OK
const uu1:U|U[] = 2     // OK

变量t0 既是T 又是T[]T 的数组) - 只是为了向您展示这样的事情是可能的。 t1u0u1都是编译错误。

不过,uu0uu1 都可以。

【讨论】:

    猜你喜欢
    • 2020-08-05
    • 2023-01-10
    • 2019-10-25
    • 1970-01-01
    • 2021-11-26
    • 2022-01-13
    • 2020-03-16
    • 1970-01-01
    • 2019-07-23
    相关资源
    最近更新 更多