【问题标题】:How can I narrow the typing of `T extends {}` to require `keyof T` to always be sting?如何缩小 `T extends {}` 的输入范围以要求 `keyof T` 始终是刺痛的?
【发布时间】:2021-08-29 14:19:00
【问题描述】:

我目前有这种映射类型,它在很多情况下都很好用:

type WithKeyPrefix<P extends string, T extends {}> = {
  [K in Extract<keyof T, string> as `${P}/${K}`]: T[K];
};

但是,我不能让它拒绝包含非字符串键的对象。到目前为止,我已经尝试了几种不同的解决方案,但都没有我想要的效果:

type WithKeyPrefix<P extends string, T extends {}> = {
  [K in Extract<keyof T, string> as `${P}/${K}`]: T[K];
} & {
  [K in Exclude<keyof T, string>]: never;
};
type WithKeyPrefix<P extends string, T extends Record<string, unknown>> = {
  [K in Extract<keyof T, string> as `${P}/${K}`]: T[K];
};

第一个没有明显区别。当T 是具有有限键的接口时,第二个会产生此错误:

TS2344: Type 'Foo' does not satisfy the constraint 'Record<string, unknown>'.
  Index signature is missing in type 'Foo'.

有没有办法以我想要的方式限制T 的类型?


额外问题:即使T 被限制为Record&lt;string, unknown&gt;,为什么还需要Extract&lt;keyof T, string&gt;

我已经遇到了this question,但是那里的解决方案是有效的变通方法,在该问题的上下文中完全有效,但在我的情况下不起作用;因此提出了新问题。

【问题讨论】:

    标签: typescript


    【解决方案1】:

    要拒绝具有非字符串属性的对象,您可以将类型重写为:

    type WithKeyPrefix<
        P extends string,
        T extends object & (keyof T extends string ? {} : "Must have only string keys"),
    > = {
        [K in Extract<keyof T, string> as `${P}/${K}`]: T[K];
    };
    

    仅字符串键约束的功劳归于这个伟大的answer

    playground link

    至于Extract&lt;keyof T, string&gt;,它是必需的,因为扩展Record&lt;string, any&gt; 的东西不是guaranteed 只有string 键。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-05-30
      • 2022-01-21
      • 1970-01-01
      • 1970-01-01
      • 2021-07-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多