typescript - 如何指定排除已知继承索引键的类索引签名?

标签 typescript typescript-generics

我想创建一个继承类的类,并为父类中不存在的所有新类属性指定索引签名。

考虑这样一种情况,您希望为搜索查询指定某种格式,该格式可以在字段上采用搜索词数组,并且继承自通用查询类。

class Query {
  limit = 25;
  offset?: number;
  constructor() { /* do stuff */ }
}

class FieldSearchQuery extends Query {
  [key: Exclude<string, keyof Query>]: string[]; // not valid, but captures the gist
  constructor() { super(); /* do stuff */ }
}

有什么替代方案吗?请注意,有一个现有的基类,并且我的目标是缩小子类的类型,以便它可以使用不与父键相交的任何键值 我们应该能够对与这些未知键关联的值进行类型检查,以确保其属于已定义的类型(在上面的示例中为字符串数组)。

我一直在查看高级类型文档,感觉好像我一定错过了一些东西,因为似乎完成此任务的所有工具都存在。

编辑: 我刚刚想出了一个可能的改进,您至少可以排除父级中不存在的所有值类型:

class Query {
  limit = 25;
  offset?: number;
  constructor() { /* do stuff */ }
}

class FieldSearchQuery extends Query {
  [key: string]: Query[keyof Query]|string[]; // valid, but overly broad
  constructor() { super(); /* do stuff */ }
}

最佳答案

您确定这里的模式正确吗?因为如果你在一个类上指定索引签名,那么它不仅会在类属性上,还会在所有方法上。

class B {
  [key: string]: string[]

  foo(): number { // Property 'foo' of type '() => number' is not assignable to string index type 'string[]'.
    return 1
  }
}

实现解决方案的一种方法是遵循 intersection types example在 typescript 文档中。

我的解决方案是在类上声明一个字段,并指定其类型。

type QueryParams = { [key: string]: any } & {
  limit: number
  offset?: number
}

class Query<T extends QueryParams> {
  params: T
  constructor(params: Partial<T>) {
    this.params.limit = params.limit === undefined ? 25 : params.limit
  }
}

type FieldSearchQueryParams = { [key: string]: string[] } & {
  limit: number
  offset?: number
}

class FieldSearchQuery extends Query<FieldSearchQueryParams> {
  constructor(params: Partial<FieldSearchQueryParams>) {
    super(params)
    // do stuff
  }
}

关于typescript - 如何指定排除已知继承索引键的类索引签名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57899147/

相关文章:

javascript - Angular 2 : Binding and Callbacks

javascript - TypeScript:在对象扩展方法中推断 <this> 的类型

typescript - Angular2,通过字符串/名称手动解析类型

typescript - 如何修复错误 TS2339 - 'HTMLElement' 上不存在属性

typescript - 在 TypeScript 中,如何创建一个通用函数,根据给定的类名和函数来推断函数的参数?

typescript - 如何在 Typescript 中测试泛型类型?不是泛型类型的实现,而是作为类型保护?

typescript - react-native run-android 出现错误 : A problem occurred evaluating project ':app' . ([androidx.appcompat :appcompat:1. 1.0-rc01])

node.js - Nestjs:如何使用nest/cli 从nestjs monorepo 中删除特定应用程序

typescript - 没有泛型的类型推断?

TypeScript 条件通用接口(interface)作为参数(数组或对象,基于 bool 值)