简体   繁体   English

Typescript 内联 object 构造函数与 generics 导致类型太宽

[英]Typescript inline object constructor with generics results in too broad type

For a project I needed to create a type with two type generics to create single-key objects:对于一个项目,我需要创建一个具有两种类型 generics 的类型来创建单键对象:

type MyVariant<K extends string, V> = {
    [key in K]: V
}

To create objects of this type I've written the following function:为了创建这种类型的对象,我编写了以下 function:

function createVariant<K extends string, V>(key: K, value: V): MyVariant<K, V>  {
    return {
        [key]: value
    };
}

This function uses the same generic types for the input key and value as for the resulting variant.此 function 对输入键和值使用与生成的变体相同的通用类型。 When using the shorthand inline constructor for the resulting object, typescript complains with the following message: Type '{ [x: string]: V; }' is not assignable to type 'MyVariant<K, V>'当为生成的 object 使用简写内联构造函数时,typescript 抱怨以下消息: Type '{ [x: string]: V; }' is not assignable to type 'MyVariant<K, V>' Type '{ [x: string]: V; }' is not assignable to type 'MyVariant<K, V>'

In my understanding the key type x shouldn't be of type string but of type K as this is the type it was given from the function parameters.据我了解,键类型x不应该是字符串类型,而是K类型,因为这是从 function 参数中给出的类型。 To make typescript accept the return value, the function needs to be modified like so:要使 typescript 接受返回值,需要像这样修改 function:

function createVariant<K extends string, V>(key: K, value: V): MyVariant<K, V>  {
    return {
        [key]: value
    } as MyVariant<K, V>;
}

In my opinion this is an unnecessary cast as the resulting type already matches the required output type.在我看来,这是不必要的转换,因为结果类型已经与所需的 output 类型匹配。 Is there a better way to build an object of MyVariant from generics that is accepted by typescript without having to cast the type to the required output? Is there a better way to build an object of MyVariant from generics that is accepted by typescript without having to cast the type to the required output?

This is a great case for using the type utility Record<Keys, Type> : you don't need MyVariant or the explicit return type for TS to correctly infer all of the information in your question:这是使用类型实用程序Record<Keys, Type>的一个很好的案例:您不需要MyVariant或 TS 的显式返回类型来正确推断您问题中的所有信息:

function createVariant <K extends string, V>(key: K, value: V) {
  return { [key]: value } as Record<K, V>;
}

TS Playground TS游乐场

Note: I'm definitely not against explicit return types注意:我绝对不反对显式返回类型

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM