【问题标题】:TypeScript create new interface from existing interface and change type of all propertiesTypeScript 从现有接口创建新接口并更改所有属性的类型
【发布时间】:2021-11-18 04:33:55
【问题描述】:
interface UserFlags {
  isDev: boolean;
  isAdmin: boolean;
  isMod: boolean;
}

const flagPositions: FlagPositions<UserFlags> = {
  isDev: 0,
  isAdmin: 1,
  isMod: 2,
};

您将如何实现FlagPositions,以便将1 个泛型参数传递给{ [name: string]: boolean } 类型的接口,并要求接口的所有属性都存在于新接口中,但类型为number

我使用keyof 尝试了各种方法,但都没有奏效。

编辑:发布后我得到了这个工作,但我希望它是一个界面

type FlagPositions<F> = {
  [K in keyof Required<F>]: number;
};

【问题讨论】:

    标签: javascript node.js typescript typescript-generics


    【解决方案1】:

    您希望FlagPositions&lt;T&gt; 成为mapped type,其键与keyof T 相同,但其值为number。你可以这样写:

    type FlagPositions<T> = { [K in keyof T]: number };
    

    并验证它是否如您所愿:

    const flagPositions: FlagPositions<UserFlags> = {
        isDev: 0,
        isAdmin: 1,
        isMod: 2,
    };
    

    请注意,constrain T{[name: string]: boolean}Record&lt;keyof T, boolean&gt; 不是必须的,但您可以根据需要这样做:

    type FlagPositions<T extends Record<keyof T, boolean>> =
        { [K in keyof T]: number };
    
    
    declare const oops: FlagPositions<{ a: number }>; // error!
    // ---------------------------->  ~~~~~~~~~~~~~
    //   Types of property 'a' are incompatible.
    

    您不能将FlagPositions&lt;T&gt; 设为interface,因为接口需要在编译时知道键,而T 是通用的并且可以具有各种键。但是,一旦您拥有具有已知键的 FlagPositions&lt;UserFlags&gt; 类型(它们是 isDevisAdminisMod),那么您可以创建一个 interface 扩展 that: p>

    interface UserFlagPositions extends FlagPositions<UserFlags> { }
    
    const u: UserFlagPositions = {
        isDev: 2,
        isAdmin: 1,
        isMod: 0
    }
    

    Playground link to code

    【讨论】:

    • 非常感谢。可以转成界面吗?
    • 你可以写interface UserFlagPositions extends FlagPositions&lt;UserFlags&gt; {}。但是您正在更改问题的范围,任何进一步的范围更改可能都需要单独发布
    • 对不起,我不清楚。一个界面是我最初想要的,但是因为它可以工作,所以一切都很好
    猜你喜欢
    • 1970-01-01
    • 2014-01-21
    • 1970-01-01
    • 2016-07-18
    • 2021-05-11
    • 2021-06-28
    • 2020-01-13
    • 2021-05-16
    • 2020-05-04
    相关资源
    最近更新 更多