在 TypeScript 泛型中使用“extends”关键字

jos*_*son 5 generics typescript

我不明白为什么下面的代码会导致错误。在这个简单的示例中,Component正如预期的那样,该类没有任何问题。State但是,明确定义为从 扩展的通用实现BaseState似乎并未发送由 提供的类型信息BaseState,从而导致错误。

interface BaseState {
    on: boolean;
    color: string;
};

class Component {
    state: BaseState;

    constructor(state: BaseState) {
        this.state = state;
    }

    setState(partialState: Partial<BaseState>) {
        this.state = { ...this.state, ...partialState };  // no error
    }

    onInput({ value }: { value: number }) {
        this.setState({ on: value > 0 });  // no error
    }
}

class GenericComponent<State extends BaseState> {
    state: State;

    constructor(state: State) {
        this.state = state;
    }

    setState(partialState: Partial<State>) {
        this.state = { ...this.state, ...partialState };  // error: Spread types may only be created from object types.
    }

    onInput({ value }: { value: number }) {
        this.setState({ on: value > 0 });  // error: Argument of type '{ on: boolean; }' is not assignable to parameter of type 'Partial<State>'
    }
}
Run Code Online (Sandbox Code Playgroud)

我在这里缺少什么?

Edu*_*hov 1

请注意,这并不是上述问题的精确解决方案,而只是一种解决方法。然而,它太长了,无法容纳评论。

关于第二个错误,即“Argument of type '{ on: boolean; }' is not assignable to parameter of type 'Partial'”,社区中围绕此主题进行了一些讨论,例如https://github.com /Microsoft/TypeScript/issues/12793https://github.com/DefinitelyTyped/DefinitelyTyped/pull/13155,尽管我找不到与您的场景完全匹配的任何内容。

由于某种原因 TS 确实无法推断出Partial<State>to的可分配性Partial<BaseState>,尽管State extends BaseState.

例如,以下代码段会导致错误。

class SampleClass<State extends BaseState> {
    baseState: Partial<BaseState>;

    method(state: Partial<State>): void {
        this.baseState = state; // Type 'Partial<State>' is not assignable to type 'Partial<BaseState>'.
    }
}
Run Code Online (Sandbox Code Playgroud)

这对我来说很奇怪,我建议向 TypeScript 社区提交建议以供考虑。至少他们可以解释是否例外以及原因。

在上面给出的特定情况下,我建议按以下方式显式转换部分的类型。

class GenericComponent<State extends BaseState> {
    state: State;

    constructor(state: State) {
        this.state = state;
    }

    setState(partialState: Partial<State>) {
        //  Some logic here
    }

    onInput({ value }: { value: number }) {
        this.setState({ on: value > 0 } as State); 
    }
}
Run Code Online (Sandbox Code Playgroud)

据我所知,这段代码仍然是类型安全的,并且遵守State.