Typescript 假定属性类型为 T |属性 ["key"] 而不仅仅是 T

标签 typescript typescript-generics

假设我们有一个如下定义的类型:

type PropsBase<T> = {
    optionalProp?: T;
} 

type Props<T, TAdditionalProps extends object> = PropsBase<T> & TAdditionalProps

基本上我有一个公共(public)属性对象,然后子类可以根据需要添加更多属性。 然后我想这样使用它:

type State<T> = {
    value: T;
}

abstract class Base<T, TAdditional extends object = {}> {
    state: State<T>;
    constructor(props: Readonly<Props<T, TAdditional>>) {
        this.state = {
            value: props.optionalProp || this.fallbackValue() // ERROR!
        }
    }

    abstract fallbackValue(): T;
}

这会导致以下错误:

TS2322: Type 'T | Props<T, TAdditional>["optionalProp"]' is not assignable to type 'T'.
   'T' could be instantiated with an arbitrary type which could be unrelated to 
   'T | Props<T, TAdditional>["optionalProp"]'.

如果我做optionalProp不是可选的(删除 ? )然后它可以工作,如果我删除 Readonly 它也可以工作从构造函数中,只需使用 Props<T, TAdditional>相反。

所以我的问题是:为什么会发生这种情况?有没有办法仍然使用 Readonly这里有一个可选属性?

附注我有strict: true在我的 tsconfig.json 中。我知道如果我将其设置为 false它会起作用的。

最佳答案

我认为从||切换到 ??解决您的问题。

Playground

type PropsBase<T> = {
    optionalProp?: T;
} 

type Props<T, TAdditionalProps extends object> = PropsBase<T> & TAdditionalProps

type State<T> = {
    value: T;
}

abstract class Base<T, TAdditional extends object = {}> {
    state: State<T>;
    constructor(props: Readonly<Props<T, TAdditional>>) {
        this.state = {
            value: props.optionalProp ?? this.fallbackValue()
        }
    }

    abstract fallbackValue(): T;
}

关于Typescript 假定属性类型为 T |属性 ["key"] 而不仅仅是 T,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68440372/

相关文章:

typescript - 具有动态和静态属性的接口(interface)

typescript - 函数返回类型取决于是否传递可选参数

javascript - 函数链不工作 Angular 5

angular - 声明具有通用类型的组件

typescript - 区分 typescript 类型中的装饰类方法

typescript - 如何缩小派生类的只读属性的类型?

angular - Firebase 5.8^ sendEmailVerification

angular - 如何在 Angular 子组件中插入html?

typescript - 推断列数组中 rowData 和 cellData 的类型

Typescript - 为什么没有相应地强制实现接口(interface)