我正在使用这个函数,它重建初始对象,但递归地将每个值转换为BigNumbers.

export const castObjectValuesToBigNumber = function(initialObj: StringMap, nestedProp?: string) {

    let _castedObj: StringMap = {};

    for(const [property, value] of Object.entries(initialObj)) {

        if(typeof(value) === "object" && !(value instanceof BN)) {
            const newVal = castObjectValuesToBigNumber(value, property);
            _castedObj = { ..._castedObj, ...newVal };
        } else {
            if(nestedProp) {
                if(!_castedObj[nestedProp]) _castedObj[nestedProp] = {};
                _castedObj[nestedProp][property] = BigNumber.from(value.toString());
            } else {
                _castedObj[property] = BigNumber.from(value.toString());
            }
        }
    }

    return _castedObj;
}

我想让它的返回类型与initialObj类型相同,但将End值设置为BigNumber类型.

示例:

const myValue = {
   propertyA: new BN(105),
   propertyB: {
      propertyC: new BN(1),
      propertyD: new BN(2),
      propertyE: new BN(3)
   },
   propertyF: {
      propertyG: new BN(4)
   }
}

我希望如果我把这个值作为我的函数的一个参数,TypeScrip会自动返回这个类型:

{
   propertyA: BigNumber,
   propertyB: {
      propertyC: BigNumber,
      propertyD: BigNumber,
      propertyE: BigNumber
   },
   propertyF: {
      propertyG: BigNumber
   }
}

我try 了很多使用泛型类型和嵌套类型的方法,但我总是会遇到某种类型的错误.

Here is a Minimum Reproducible 示例:

/////////////////////
/// DECLARATIONS

interface StringMap { [key: string]: any }

class BN {
    value;
    constructor(num: number | string) {
        this.value = num;
    }

    _isBN() {
        return true;
    }
}

class BigNumber {
    value;
    constructor(num: number | string) {
        this.value = num;
    }

    _isBigNumber() {
        return true;
    }
}

const myValue = {
   propertyA: new BN(105),
   propertyB: {
      propertyC: new BN(1),
      propertyD: new BN(2),
      propertyE: new BN(3)
   },
   propertyF: {
      propertyG: new BN(4)
   }
};

/////////////////////
/// FUNCTION
export const castObjectValuesToBigNumber = function(initialObj: StringMap, nestedProp?: string) {

    let _castedObj: StringMap = {};

    for(const [property, value] of Object.entries(initialObj)) {

        if(typeof(value) === "object" && !(value instanceof BN)) {
            const newVal = castObjectValuesToBigNumber(value, property);
            _castedObj = { ..._castedObj, ...newVal };
        } else {
            if(nestedProp) {
                if(!_castedObj[nestedProp]) _castedObj[nestedProp] = {};
                _castedObj[nestedProp][property] = new BigNumber(value.toString());
            } else {
                _castedObj[property] = new BigNumber(value.toString());
            }
        }
    }

    return _castedObj;
}

/////////////////////
/// TEST

/*
    Result is of type StringMap while I would like it to be :

    {
        propertyA: BigNumber,
        propertyB: {
            propertyC: BigNumber,
            propertyD: BigNumber,
            propertyE: BigNumber
        },
        propertyF: {
            propertyG: BigNumber
        }
    }
    
*/

const myCastedValue = castObjectValuesToBigNumber(myValue); 

推荐答案

我们将用于将每个BN递归更改为BigNumber的类型可能如下所示:

type CastToBigNumber<T> = T extends BN ? BigNumber : {
    [K in keyof T]: CastToBigNumber<T[K]>
};

如果TBN,那么我们将其更改为BigNumber,否则它是一个对象,并且我们更改其所有属性.

现在,使用泛型参数的函数定义如下所示:

export const castObjectValuesToBigNumber = function<Initial extends StringMap>(initialObj: Initial, nestedProp?: string): CastToBigNumber<Initial> {

Playground

Typescript相关问答推荐

如何创建泛型类型组件来使用React Native的FlatList或SectionList?'

动态调用类型化函数

未在DIST中正确编译TypeScrip src模块导入

匿名静态类推断组成不正确推断

TypeScrip 5.3和5.4-对`Readonly<;[...number[],字符串]>;`的测试版处理:有什么变化?

返回具有递归属性的泛型类型的泛型函数

在类型脚本中的泛型类上扩展的可选参数

<;T扩展布尔值>;

在数据加载后,如何使用NgFor在使用异步管道的可观测对象上生成子组件?

如何创建一家Reduxstore ?

是否可以判断某个类型是否已合并为内部类型?

保护函数调用,以便深度嵌套的对象具有必须与同级属性函数cargument的类型匹配的键

如何过滤文字中的类对象联合类型?

如何缩小函数的返回类型?

自定义 Select 组件的类型问题:使用带逗号的泛型类型<;T与不带逗号的<;T&>;时出错

如何从一个泛型类型推断多个类型

字幕子集一个元组的多个元素

如何将元素推入对象中的类型化数组

传入类型参数<;T>;变容函数

如何使用 AWS CDK 扩展默认 ALB 控制器策略?