条件类型没有适当的限制

时间:2019-06-12 21:43:00

标签: typescript

我有不同类型的视图,这些视图在它们具有的属性和可以更改的属性方面有所不同。我尝试创建一个updateView函数,该函数将视图和一些更改传入,合并,然后在后端更新视图。该函数应根据传入的视图类型限制传入的更改,但这不能正常工作。我在下面发布了一个示例。

如何更改UpdateView接口以适当限制可以传入的更改?

interface BaseView {
    immutableProp?: string;
    mutableProp?: string;
    name: string;
    isCustom: boolean;
}

interface StandardView extends BaseView {
    isCustom: false;
}

interface CustomView extends BaseView {
    isCustom: true;
}

type View = StandardView | CustomView

type StandardMutableFields = Partial<Pick<StandardView, "mutableProp">>
type CustomMutableFields = Partial<Pick<CustomView, "mutableProp" | "name">>


interface UpdateView {
    <T extends View>(viewToChange: T, changes: T extends CustomView ? CustomMutableFields : StandardMutableFields): T
}

const updateView: UpdateView = (viewToChange, changes) => {
    const updatedView = { ...viewToChange, changes };
    // SAVE TO SERVER
    return updatedView;
}

const changeName = (view: View, name: string) => {
    updateView(view, { name: "this is allowed but shouldn't be" }) // should require a check to ensure the view is custom
}

1 个答案:

答案 0 :(得分:1)

我认为这里最简单的解决方案(至少从我在问题中看到的)是删除条件类型和泛型函数,而只是使用重载。

本质上无法使用可能的参数类型的并集来调用重载,因此该调用可以使用CustomViewStandardView进行调用,但不能使用两者的并集进行调用,因此自然会迫使您区别对待在执行通话之前,两者之间:

interface UpdateView {
    (viewToChange: CustomView, changes: CustomMutableFields): CustomView
    (viewToChange: StandardView, changes: StandardMutableFields): StandardView
}

const updateView: UpdateView = (viewToChange: CustomView | StandardView, changes : CustomMutableFields | StandardMutableFields) => {
    const updatedView = { ...viewToChange, changes };
    // SAVE TO SERVER
    return updatedView as any;
}

const changeName = (view: View, name: string) => {
    updateView(view, { name: "this is allowed but shouldn't be" }) // err
    if (view.isCustom) {
        updateView(view, { name: "this is allowed but shouldn't be" }) // ok
    }
}