繁体   English   中英

只定义对象的键和自动生成值的类型

[英]Define only object's key and auto generate value's type

我正在尝试做类似的事情:

type Sizes = 'small' | 'large';

const CONFIG_BY_SIZE: Record<Sizes, any> = {
    small: {
        a: ...,
        b: ...,
        c: ...,
    },
    large: {
        a: ...,
        b: ...,
        c: ...,
    },
}

它有效,但是当我尝试键入CONFIG_BY_SIZE.large. abc没有自动完成。 我认为这是因为我将值定义为任何。 值本身非常大,所以如果可能的话,我更喜欢它是自动生成的。

我的目标是将键定义为Sizes但我仍然可以自动完成该值。 我如何实现这一目标?

谢谢!

如果您想应用某种类型约束,但从值中推断出比该约束更具体的内容,那么这就是函数的泛型参数所做的。

所以我认为你需要提供一个函数来允许打字稿进行推断:

function createConfigBySize<T extends Record<Sizes, unknown>>(config: T): T {
  return config
}

这样做是将T映射到extends Record<Sizes, unknown> 打字稿准确指出它是什么子类型,并将其保存到T 然后将返回类型设置为T以获取推断的任何内容。

现在你可以这样做:

const CONFIG_BY_SIZE = createConfigBySize({
    small: {
        a: 123,
        b: 'abc',
        c: false,
    },
    large: {
        a: { cool: true },
        b: null,
        c: [1,2,3],
    },
})

产生这种类型:

{
    small: {
        a: number;
        b: string;
        c: boolean;
    };
    large: {
        a: {
            cool: boolean;
        };
        b: null;
        c: number[];
    };
}

如果您使用无效的大小键,您仍然会进行类型检查:

createConfigBySize({
  small: { foo: 123 },
  medium: { bar: 123 }, // type error
})

工作操场


也就是说,如果你想small.a是同一类型large.a这不是正确的解决方案。 在这种情况下,您确实应该为任何类型创建一个接口。 任何需要在多个地方重用类型的东西,正式声明该接口是一个非常好的主意。

您可以使用类似的语法来强制对象具有联合类型中每个条目的键:

type Sizes = 'small' | 'large';
type Keys = 'a' | 'b' | 'c';

const CONFIG_BY_SIZE: Record<Sizes, { [key in Keys]: any }> = {
    small: {
        a: 1,
        b: 2,
        c: 2,
    },
    large: {
        a: 2,
        b: 2,
        c: 2,
    },
}

在此处输入图片说明

您也可以将其设为通用类型。

代码示例在这里

暂无
暂无

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

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