如何在Typescript类中将客户端传递的配置对象与默认配置对象合并?

如何在Typescript类中将客户端传递的配置对象与默认配置对象合并?,typescript,Typescript,在编写纯Javascript时,我通常使用“config”属性构建类,其键具有一些默认值,例如: class MyClass{ config = { someProp:true, otherProp:5 } constructor(config){ for(let prop in config){ this.config[prop] = config[prop] } } }

在编写纯Javascript时,我通常使用“config”属性构建类,其键具有一些默认值,例如:

class MyClass{
    config = {
        someProp:true,
        otherProp:5
    }

    constructor(config){
        for(let prop in config){
            this.config[prop] = config[prop] 
        }
    }
}
这非常方便,因为我可以循环通过传递的对象并覆盖默认值(如果提供了值)

在Typescript中,我尝试了以下方法:

class MyClass{
    config = {
        someProp:true,
        otherProp:5
    }  

    constructor(config?: { someProp?: boolean,otherProp?:number  }) {
        if (config) {
            for (let prop in config) {
                this.config[prop] = config[prop]
            }
        }

    }
}
constructor(config?: { someProp?: boolean,otherProp?:number  }) {
    Object.assign(this.config, config);
}
我得到以下错误:

元素隐式具有“any”类型,因为表达式的类型为 “string”不能用于索引类型“{someProp:boolean;otherProp: 编号;}。未找到具有“string”类型参数的索引签名 在类型{someProp:boolean;otherProp:number;}上找到

我或多或少理解这个错误的含义,但我想我在这里的整个方法非常“类似JS”,应该改变


在Typescript中,传统的、简单的方法是什么?这样做的目的是快速将提供的属性与默认属性合并,而无需重复各种检查。

您可以像这样结束运行错误:

class MyClass{
    config = {
        someProp:true,
        otherProp:5
    }  

    constructor(config?: { someProp?: boolean,otherProp?:number  }) {
        if (config) {
            for (let prop in config) {
                this.config[prop] = config[prop]
            }
        }

    }
}
constructor(config?: { someProp?: boolean,otherProp?:number  }) {
    Object.assign(this.config, config);
}

这种方式会将JavaScript-y部分隐藏在
对象后面

但是如果你想要更好的类型检查,这是TypeScript,对吗?:-)-我可能会替换config属性并使用扩展语法:

class-MyClass{
配置={
是的,
其他建议:5
}  
构造函数(配置?:{someProp?:boolean,otherProp?:number}){
如果(配置){
this.config={…this.config,…config};
}
}
}

甚至可能

class-MyClass{
配置:{someProp:boolean,otherProp:number};
构造函数(配置?:{someProp?:boolean,otherProp?:number}){
this.config={
是的,
其他提案:5,
…配置
};
}
}

如果
config
undefined
(或
null
),则扩展语法将不起任何作用

您甚至可以使用定义的类型来避免在两个地方编写相同的道具:

interface MyClassConfig {
    someProp: boolean;
    otherProp: number;
}
class MyClass {
    config: MyClassConfig;
    constructor(config?: Partial<MyClassConfig>) {
        this.config = {
            someProp: true,
            otherProp: 5,
            ...config
        };
    }
}
接口MyClassConfig{
someProp:布尔;
其他属性:数字;
}
类MyClass{
config:MyClassConfig;
构造函数(配置?:部分){
this.config={
是的,
其他提案:5,
…配置
};
}
}

看来这可能就是你想要的

您也可以选择在别处声明
config
的类型(类型/接口声明),然后使用
Partial
作为构造函数参数

因此:

接口配置{someProp:boolean;otherProp:number;}
类MyClass{
配置:配置={
是的,
其他建议:5
}  
构造函数(配置?:部分){
this.config={…this.config,…config}
}
}

这是否回答了您的问题?问题是您的
for(让prop进入配置)
->TypeScript将prop的值推断为“string”,而不是
“someProp”|“otherProp”
dwjohnston.。我不明白。你能解释一下吗?请阅读链接帖子中的答案。按照这里的答案,FWIW是最干净的解决方案。但是理解TypeScript中的类型推断和类型加宽/缩小很重要,您将再次遇到它。我需要首先学习Typescript:D中Partial的概念。我对这一切都是新手。@I.brod
Partial
类型与type
T
类型完全相同,除非所有属性都是可选的。