【问题标题】:How to change the type of an object property dynamically in typescript?如何在打字稿中动态更改对象属性的类型?
【发布时间】:2023-02-26 05:06:59
【问题描述】:

我有一个具有某些属性的对象,我希望能够将其设置为 stringnumber

const identityConfig = {
  [configID]: {
    metadata: {
      config: 'STATIC',
      value: null,
    },
  },
};

我希望这个 metadata.value 属性是数字或字符串,但默认值为 null。

我在另一个对象中有这个identityConfig对象,ACCOUNT

export const ACCOUNT = {
  name: '',
  identity: identityConfig
  setIdentityValue: (metadata: IdentityMetadata) => {
  identityConfig[configID].metadata = metadata
  }
  };

这是参数类型:

type IdentityMetadata = { config: string; value: string | number };

所以我将这个 setIdentityValue 方法公开并使用它来传递 metadata 属性,它有一个 value 属性,可以是字符串或数字。

问题是,这是我得到的错误

属性“值”的类型不兼容。输入'字符串| number' 不可分配给类型 'null'。

我怎样才能将值设置为这些类型中的任何一种,同时还给它一个默认值 null?我试图将IdentityMetadata中的value类型更改为string | number | null ,但这也不起作用。

【问题讨论】:

    标签: typescript


    【解决方案1】:

    考虑以下代码

    const metadataValue: string | number | null = null; // Does compile
    

    在打字稿中,null 是一个值,也是一种类型。
    允许键入您的值 null 确实允许使用 null 作为值对其进行初始化。

    我试图将 IdentityMetadata 中的值类型更改为 string |编号 | null 但这也不起作用。

    错误是什么? 如果 identity.metadata.value 是用 string | number | null 键入的,它应该编译时将 null 赋值。

    一个常见的错误是期望 value 总是分配给 string | number,例如:

    const display = (param: string | number): void => {
        console.log(param);
    }
    
    const value: string | number | null = null;
    display(value); // Does not compile
    

    【讨论】:

    • 如果我将IdentityMetadata 变成{ config: string; value: string | number | null },我得到的错误是Type 'string | number | null' is not assignable to type 'null'. Type 'string' is not assignable to type 'null'
    • 确保启用了 strictNullChecks:typescriptlang.org/tsconfig#strictNullChecks
    【解决方案2】:

    您代码中的问题是您没有输入 identityConfig 对象,因此 Typescript 假设您创建它的类型是唯一允许的类型.这称为“type inference”,意味着这也是不可能的:

    let foo = 3; // notice: no type provided!
    foo = "hello!"; // `Type 'string' is not assignable to type 'number'.`
    
    

    那么,您需要做的就是输入对象!

    interface IdentityMetadata {
      config: string;
      value: string | number | null;
    }
    
    interface IdentityConfig {
      [key: string]: {
        metadata: IdentityMetadata,
      };
    }
    const identityConfig: IdentityConfig = {
      [1]: {
        metadata: {
          config: "STATIC",
          value: null,
        },
      },
    };
    
    export const ACCOUNT = {
      name: "Foo",
      identity: identityConfig,
      setIdentityValue: (metadata: IdentityMetadata) => {
        identityConfig[1].metadata = metadata;
      },
    };
    
    

    您可以在Playground and see for yourself 中运行它。

    【讨论】:

    • 我刚刚在TS Playground 中重现了这个问题。
    • @Altus 我已经更新了我的答案!
    猜你喜欢
    • 1970-01-01
    • 2021-06-19
    • 2017-03-04
    • 2019-10-27
    • 2020-10-06
    • 2021-12-16
    • 1970-01-01
    • 1970-01-01
    • 2017-09-06
    相关资源
    最近更新 更多