typescript - 我可以在不通过断言强制类型的情况下修复此 typescript 编译器错误吗?

标签 typescript immutability readonly mapped-types type-assertion

在此typescript playground我已经编写了一个最小的 Immutable(递归只读)类型和一个存储 Immutable 的 Store 接口(interface)。

目前我的分区存储类的 read() 和 write() 函数存在编译错误,我想通过正确注释类型而不是进行类型断言来解决这个错误。以下是顶级定义。

interface Store<State>{
  read:() => Immutable<State> 
  write:(state:Immutable<State>) => Immutable<State>
}

export type ImmutableObject<T> = 
  {
    readonly [K in keyof T]: Immutable<T[K]>;
  }
;

export type Immutable<T> = T extends object
  ? ImmutableObject<T>
  : T extends string | number | boolean | null
  ? Readonly<T>
  : never;

当我从商店派生分区子商店时,我的问题就出现了。这意味着只需使用其声明的键之一选择 State 的子部分,然后从中创建一个 Store。

这是我的草稿实现,它需要注释断言来抑制编译错误...

class BasicStorePartition<SuperState, Key extends keyof SuperState> 
  implements Store<SuperState[Key]>{
    constructor(
    readonly store: Store<SuperState>,
    readonly key: Key,
  ) {}
  //this line requires the commented type assertion in order to compile
  read = () => this.store.read()[this.key] // as unknown as Immutable<SuperState[Key]>
  write = (state:Immutable<SuperState[Key]>) => { 
    this.store.write({
      ...this.store.read(),
      [this.key]:state
    });
    return this.read()
  }
}

编译报错如下。我希望它们解析为相同的类型,并且不知道作为键的 string 来自哪里,因为在源代码中没有以这种方式注释键...

Type 'ImmutableObject<SuperState[string]>' is not assignable to type 'Immutable<SuperState[Key]>'

Type 'Immutable<SuperState>[Key]' is not assignable to type 'Immutable<SuperState[Key]>'

可以通过简单地声明类型信息来修复编译,例如...

as unknown as Immutable<SuperState[Key]>

我想解决此编译错误,以便类型解析并与预期的只读类型对齐,而无需绕过编译器。任何人都可以找到执行此操作的方法吗?

欢迎提出有关改进该方法的任何其他意见。

最佳答案

恐怕编译器无法毫无疑问地知道你希望它推断的类型是正确的,即使在实践中它们可能是正确的(TypeScript 中有很多边缘情况) .

以下是我对您的问题的观察:

  • object 类型已弃用,参见 this question .显然人们在使用它时遇到了问题。

  • 在我看来,如果您 99% 确定它是正确的,那么在您的实现中使用类型断言是可以的。编译器并不完美,而且永远不会。但是永远不要从你的公共(public)接口(interface)返回错误的类型,或者强制你的函数的用户做断言。我遇到过很多公共(public)类型信息不佳或错误的图书馆,这真的很令人沮丧。

我正在编写 Rimbu immutable collections library ,其中我已尽最大努力使类型信息尽可能正确和精确。但是,如果您可以这么说,看看“幕后”,代码中充满了类型断言,因为编译器,尤其是在更高级的情况下,只需要帮助。这在任何类型化语言中都是如此,但在 TypeScript 中更为常见,因为它具有如此多的特性。只要我能为我的用户提供更好的体验,我对此没有意见。

作为旁注,您的类型定义非常接近 Rimbu's Immutable definition

关于typescript - 我可以在不通过断言强制类型的情况下修复此 typescript 编译器错误吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66919250/

相关文章:

C# - 使字段/属性有条件地只读

C# - 此声明的字符串是否被视为常量?

perl - 任何人都可以向我解释这个只读异常吗?

visual-studio - Visual Studio 2017 删除/禁用文件嵌套

typescript - 缩小捕获中的错误类型

java - 不可变对象(immutable对象)中的私有(private)最终字段与公共(public)最终字段(java)

Kotlin:val mutableList与var immutableList。什么时候使用?

typescript - 有没有办法在没有任何模块加载器的情况下使用 angular 2?

javascript - Webpack 5 错误 : Should not import the named export 'foo' (imported as 'bar' ) from default-exporting module

javascript - 我们可以在任何地方使用 `const` 而不是 `let` 吗?