typescript 怎么动态定义数据类型?

目标对象为

{
    name:'xiaoming',
    city:{value: 210000, label: 'shanghai'}
}

通过produce方法改为

{
    name:'xiaoming',
    city:210000, 
}

报错,求答案?

图中代码如下:

const produce = (obj: { [key: string]: string | { value: number | string; label: string } }) => {
  Object.keys(obj).forEach((item) => {
    if (typeof obj[item] === 'object') {
      obj[item] = obj[item].value;
    }
  });
  return obj;
};
阅读 2.8k
3 个回答

虽然 判断了 typeof obj[item] === "object",但是再次使用 obj[item] 的时候,它的类型仍然是不确定的 —— 谁说两次 []运算就一定会返回相同的东西呢?所以 if 块里的 obj[item].value 这里,obj[item] 仍然有可能是 string 类型,当然取不到 value 属性。加个临时变更可以解决这个问题

Object.keys(obj).forEach((item) => {
    const v = obj[item];
    if (typeof v === "object") {
        obj[item] = v.value;
    }
});

然后错误会标在obj[item] 上,这回是因为 v.value 的类型是 number | string,而 obj[item] 不能接受 number 类型的数据。可以再加一个判断来处理

obj[item] = typeof v.value === "string" ? v.value : `${v.value}`;

这里可以在逻辑保证类型安全的情况下用一句话搞定(但不推荐,这不是类型安全的写法,万一以后改了类型呢)

Object.keys(obj).forEach((item) => {
    obj[item] = `${(obj[item] as any).value ?? obj[item]}`;
});

类型安全的写法还可以这样(逻辑跟之前的那个类型安全的没多大区别)

Object.keys(obj).forEach((item) => {
    const v = ((it) => typeof it === "object" ? it.value : it)(obj[item]);
    obj[item] = typeof v === "string" ? v : `${v}`;
});

强转一下~

const produce = (obj: { [key: string]: string | { value: number | string; label: string } }) => {
    Object.keys(obj).forEach((item) => {
        if (typeof obj[item] === 'object') {
            obj[item] = (obj[item] as any).value ;
        }
    });
    return obj;
};
const produce = (obj: Record<string, string | { value: number | string; label: string }>) => {
    const newObj: Record<string, string | number> = {};

    Object.keys(obj).forEach((item) => {
        const _value = obj[item]

        newObj[item] = typeof _value !== 'string' ? _value.value : _value;
    });

    return newObj;
};

obj = produce(obj);

试试这个,缺点就是循环里面要搞个变量,不过小数据不影响。不太建议typeof判断'object',因为object包括数组和对象,我觉得这可能是你报错的真正原因

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进