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

问题描述

在这typescript playground 处,我编写了一个最小的不可变(递归只读)类型和一个存储不可变的 Store 接口。

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

def cap(name):
    first = name[0]
    mid = name[1:3]
    second = name[3]
    rest = name[4:]    
    return first.upper() + mid + second.upper() + rest


cap('kahasdfn')

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

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

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;

报告的编译错误如下。我希望它们能够解析为相同的类型,并且不知道作为键的 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]>'

我想解决这个编译错误,以便类型解析并与预期的只读类型对齐,而不必绕过编译器。任何人都可以看到这样做的方法吗?

欢迎任何其他关于改进方法的意见。

解决方法

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

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

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

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

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

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

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...