【问题标题】:How to remove index from typeof object in typescript如何从打字稿中的typeof对象中删除索引
【发布时间】:2019-06-16 18:28:49
【问题描述】:

使用[key: string] 将使我的类型接受任何键。我试图避免它,因为在某些地方我重新定义了属性的类型。考虑关注。

interface IObject {
  [K: string]: number;
}

const base: IObject = {
  title: 0,
  age: 3
};
type StringValue<T> = { [K in keyof T]: string };  // <-- How to remove object index


const child: StringValue<typeof base> = {
  test: "" // <-- should not be possible
  title: '' // <-- this is OK
};

【问题讨论】:

  • 如果base 不允许任意键,而只允许titleage,那么它就不是IObject。为什么要宣布它为一个?另外,StringValue&lt;T&gt; 的目的是什么? (不是我的反对票)
  • 根据建议的命名进行了更新。在简单的示例中,这不是问题。但是在像base = { title: { value: '', valid: () =&gt; true }} 这样的复杂结构中,我想确保在值和另一个接口之间建立契约。 IObject { [K: string]: IProperty }

标签: typescript generics types interface typescript2.0


【解决方案1】:

您无法真正做到这一点,因为一旦您将Base 明确键入为IObject,它就会丢失有关分配给它的内容的信息。 Base 不会在其类型中具有索引签名 属性名称。 Base 的类型是 IObject,这是一个索引签名,仅此而已。

我的猜测是您希望将 Base 限制为仅具有数字属性,但您希望捕获分配给它的对象文字的实际类型。单独的变量不能做到这一点,你需要使用一个额外的函数。函数可以具有受约束但基于实际参数推断的类型参数。

interface IObject {
    [K: string]: number;
}
function createObject<T extends IObject>(o: T) {
    return o;
}
const base = createObject({
    title: 0,
    age: 3
});
type StringValue<T> = { [K in keyof T]: string };  // <-- How to remove object index


const child: StringValue<typeof base> = {
    test: "", // <-- error
    title: '', // <-- this is OK
    age: ""
};

【讨论】:

  • 这就是我在复杂设置中所做的,但是我在通用函数 ReturnType 上遇到了问题。所以这不会编译ReturnType&lt;typeof createObject&lt;T&gt;&gt;。我想这是另一个问题。感谢您澄清这里可以做什么。
  • @EduardJacko 您无法获得应用类型参数的泛型函数的类型。没有语法。
猜你喜欢
  • 2018-08-20
  • 2017-10-27
  • 2018-08-06
  • 2023-03-28
  • 1970-01-01
  • 1970-01-01
  • 2019-12-01
  • 2018-09-10
相关资源
最近更新 更多