Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/xslt/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
typescript键和字符串的通用约束:ts2322_Typescript_Typescript Generics - Fatal编程技术网

typescript键和字符串的通用约束:ts2322

typescript键和字符串的通用约束:ts2322,typescript,typescript-generics,Typescript,Typescript Generics,我正在尝试编写一个泛型类,它保留一对指向泛型类型键的特殊指针。下面是这个MVP的一个例子 const _idKey = Symbol('_idKey') const _sortKey = Symbol('_sortKey') export interface BaseStoreConfig<T, Tid extends keyof T, Tsk extends keyof T | undefined> { idKey?: Tid sortKey?: Tsk } expor

我正在尝试编写一个泛型类,它保留一对指向泛型类型键的特殊指针。下面是这个MVP的一个例子

const _idKey = Symbol('_idKey')
const _sortKey = Symbol('_sortKey')

export interface BaseStoreConfig<T, Tid extends keyof T, Tsk extends keyof T | undefined> {
  idKey?: Tid
  sortKey?: Tsk
}

export class BaseStore<T, Tid extends keyof T & string, Tsk extends keyof T | undefined> {
  public [_idKey]: keyof T | 'id'
  public [_sortKey]?: keyof T | undefined

  constructor({
    idKey = 'id', // Errors, see below
    sortKey,
  }: BaseStoreConfig<T, Tid, Tsk>) {
    this[_idKey] = idKey
    this[_sortKey] = sortKey
  }
}

我通常理解这个错误,但在这种情况下我感到困惑。
string
的子类型如何不能分配给此类型?有什么方法可以表达这个约束吗?

我认为问题在于,Typescript实际上不支持相同值的不同类型(例如,
idKey
),这取决于该值是从调用者一侧(
Tid
未定义的
)还是从实现者一侧(
Tid
“id”)查看的
)。也有类似的问题,比如归档为bug,但我不确定它们何时会得到解决

您已将构造函数参数注释为类型
BaseStoreConfig
,其
idKey
属性的类型为
Tid |未定义的
。在尝试将默认值
“id”
分配给它时,编译器将其视为不匹配。。。因为
“id”
可能无法分配给
Tid
。提到
string
而不是特别提到
“id”
的特定错误似乎是3.9之后对TypeScript的一些更改(不确定原因,但我假设它在其他地方做了合理的事情)。如果恢复到3.9,您将看到显式提到
“id”
的错误


因此,我认为这里的解决办法是不要在分解结构中使用默认值,因为没有很好的方法来表示相同值的两种不同类型。相反,我们只需将默认值移动到构造函数的主体:

  constructor({
    idKey, sortKey,
  }: BaseStoreConfig<T, Tid, Tsk>) {
    this[_idKey] = idKey ?? "id" // okay
    this[_sortKey] = sortKey
  }
构造函数({
idKey,sortKey,
}:BaseStoreConfig){
这个[_idKey]=idKey???“id”//好的
这个[\u sortKey]=sortKey
}
现在所有的东西都编译好了,没有错误


我认为问题在于,Typescript并不真正支持相同值的不同类型(例如,
idKey
),这取决于该值是从调用者一侧(
Tid
undefined
)还是从实现者一侧(
Tid
“id”
)查看的。也有类似的问题,比如归档为bug,但我不确定它们何时会得到解决

您已将构造函数参数注释为类型
BaseStoreConfig
,其
idKey
属性的类型为
Tid |未定义的
。在尝试将默认值
“id”
分配给它时,编译器将其视为不匹配。。。因为
“id”
可能无法分配给
Tid
。提到
string
而不是特别提到
“id”
的特定错误似乎是3.9之后对TypeScript的一些更改(不确定原因,但我假设它在其他地方做了合理的事情)。如果恢复到3.9,您将看到显式提到
“id”
的错误


因此,我认为这里的解决办法是不要在分解结构中使用默认值,因为没有很好的方法来表示相同值的两种不同类型。相反,我们只需将默认值移动到构造函数的主体:

  constructor({
    idKey, sortKey,
  }: BaseStoreConfig<T, Tid, Tsk>) {
    this[_idKey] = idKey ?? "id" // okay
    this[_sortKey] = sortKey
  }
构造函数({
idKey,sortKey,
}:BaseStoreConfig){
这个[_idKey]=idKey???“id”//好的
这个[\u sortKey]=sortKey
}
现在所有的东西都编译好了,没有错误


考虑
const z:'foo'和string='id'-这将不起作用,因为“id”不可分配给“foo”,因此,如果您使用“id”以外的键传入一些t,您在这里也会遇到同样的问题。至于“有没有办法表达这个约束?”——不是100%确定你在这里要做什么。我认为您使用“id”作为默认键的设计要点,而不对T的形状进行假设,会导致打字混乱。也许你可以添加一些用法的例子,什么应该起作用,什么不应该起作用等等,我可以帮助你,我不完全理解
Tid
需要是
T
的一个键,因此
T
不能是
'foo'
,或者
Tid
没有可能的类型。不是使用<代码>键<代码>强制<代码> t>代码>作为对象吗?考虑<代码> const z:'fo'和string=id;<代码>-这将不起作用,因为“id”不可分配给“foo”,因此,如果您使用“id”以外的键传入一些t,您在这里也会遇到同样的问题。至于“有没有办法表达这个约束?”——不是100%确定你在这里要做什么。我认为您使用“id”作为默认键的设计要点,而不对T的形状进行假设,会导致打字混乱。也许你可以添加一些用法的例子,什么应该起作用,什么不应该起作用等等,我可以帮助你,我不完全理解
Tid
需要是
T
的一个键,因此
T
不能是
'foo'
,或者
Tid
没有可能的类型。使用
keyof
是否强制
t
成为对象?