首页 > 解决方案 > 关于接口“扩展”的 TypeScript 问题

问题描述

我正在尝试为查询系统编写过滤器类型。在尝试编写getItem(id)方法时,我偶然发现了这一点,我不知道为什么 Typescript 不允许这样做。

在里面我有一个函数类型,<Type extends BaseType>它不允许我使用该属性运行查询,不管它将扩展并拥有该属性id的事实。TypeBaseTypeid

f<T>部分将抛出此错误:

Argument of type '{ a: { eq: "123"; }; }' is not assignable to parameter of type 'Partial<TypePropertyFilter<T>>'.ts(2345)

/**
 * This setup should support "queries" like:
 * { id: { eq: "abc"}, someVal: { lt: 5 }}
 */

export type FilterName = 'eq' // | 'lt' | 'gt // etc...

export type FilterRecord<Type> = Record<FilterName, Type | Type[]>

export type TypePropertyFilter<Type extends {}> = {
  [P in keyof Type]: Partial<FilterRecord<Type[P]>>
}

export type Filter<Type> = Partial<TypePropertyFilter<Type>>



interface BaseType { a: string, b: number }

interface TestType extends BaseType {
  test: boolean
}

const t: TestType = { id: "123", test: "pitr"} as any

const f = <T>(f: Filter<T>) => null

const r = <T extends BaseType>() => {

  f<TestType>({
    a: {eq: "123"}, // correct (fails with other type)
    b: { eq: 4555 }, // correct (fails with other type)
    test: { eq: true } // correct (fails with other type)
  })
  f<BaseType>({
    a: {eq: "123"}, // correct (fails with other type)
    b: { eq: 4555 }, // correct (fails with other type)
    // test: { eq: true } // correctly fails, not of BaseType
  })
  f<T>({
    a: {eq: "123"}, // fails but should succeed, T extends BaseType and should at least support all that f<NodeType> does
  })
}

标签: typescript

解决方案


我认为问题在于TinT extends BaseType可能是一种类型,例如

{
  a: "foo" | "bar";
  b: number;
}

在这种情况下,您的过滤器{ a: {eq: "123"} }将不安全


推荐阅读