首页 > 解决方案 > TypeScript:条件映射类型和泛型类型参数

问题描述

我在 TypeScript 存储库中打开了一个关于条件映射类型和泛型类型参数的问题。我试图定义一个映射类型SubAddsNewPropsToSuper<Sub, Super>,它有点像extends泛型类型的约束,只是它只允许 Sub 向 Super 添加新属性,而不更改任何现有属性的类型

问题是是否可以定义这样的类型。首先是我的代码示例,第二是预期行为,第三是实际行为。

// defines a type that contains all properties of Super exactly as they are defined in Super
// and all properties of Sub that are not already defined in Super.
type SubAddsNewPropsToSuper<Sub, Super> = { [KeyOfNewPropsInSub in Exclude<keyof Sub, keyof Super>]: Sub[KeyOfNewPropsInSub] } & Super;

class Controller<TModel> {

    constructor(public model: SubAddsNewPropsToSuper<TModel, { Title: string }>) { }

    setFancyTitle() { 

        this.model.Title = "FANCY"; // works
        this.updateModel({ Title: "FANCY" }); // does not work - why?
        const x: Partial<SubAddsNewPropsToSuper<{ Title: "Foo" }, { Title: string }>> = { Title: "FANCY" }; // works
        const y: Partial<SubAddsNewPropsToSuper<TModel, { Title: string }>> = { Title: "FANCY" }; // does not work - why?
    }

    updateModel(changes: Partial<SubAddsNewPropsToSuper<TModel, { Title: string }>>) {
        // merge "changes" into "this.model"
    }
}

预期行为: 该类型SubAddsNewPropsToSuper<A, B>应该定义一个包含所有类型属性的类型B 即使B类型A定义了具有不同类型的相同属性(例如,将属性的类型从 更改string"OnlyThisString")。这背后的想法是规避“问题”,如果Controller被定义为class Controller<TModel extends { Title: string }>{ ... }在这种情况下TModel实际上可能会改变 property 的类型Title

实际行为:A如果两者都是非泛型类型,它会 按预期工作,B但如果是泛型类型,它就不起作用A

操场

标签: typescriptconditional-typesmapped-typesgeneric-type-parameters

解决方案


推荐阅读