Typescript类型推断和扩展泛型

时间:2019-01-18 02:07:14

标签: typescript

我正在尝试编写一个具有以下要求的函数:

  • 每个组都有一组项目(项目名称是随机的),每个项目 具有基于当前方向(北,东等)的值,并且 默认值以避免必须声明所有这些值。
  • 某个项目的所有值都必须是同一类型。

示例:

const group = createGroup({
    name: "group1",
    items: {
        key1: {
            description: 'i1',
            values: {
                default: 'b',
                north: 'n',
            }
        },
        key2: {
            description: 'i2',
            values: {
                default: 1,
                south: 2,
            }
        }
    }
});

此对象的输出是可以使用的对象。

console.log(group.key1) // based on current direction will return 'b' or 'n';  
console.log(group.key2); // based on current location will return 1 or 2
// key1 is of type string, key2 is of type number

我完全可以使用它,但是我的目标是在不两次声明类型或泛型的情况下完全键入它,并避免用户扩展values属性。

这是我使用的类型:

type Direction = 'north' | 'south' | 'east' | 'west';
type GroupValuesRecord<T extends string, K> = Partial<Record<T, K>> & { default: K };

type ItemConfig = {
  description: string;
  values:
    | GroupValuesRecord<Direction, string>
    | GroupValuesRecord<Direction, number>
    | GroupValuesRecord<Direction, boolean>;
};

type GroupItems = Record<string, ItemConfig>;

type GroupConfig<T extends GroupItems> = {
    name: string
    items: T
}

type OutputValue<T extends GroupItems> = { readonly [id in keyof T]: T[id]['values']['default'] };

function createGroup<T extends GroupItems>(config: GroupConfig<T>): OutputValue<T> {
    // some implementation that involves define property
}

这种类型系统的唯一缺点是可以扩展每个项目而不会显示错误 例如。

const group = createGroup({
    name: "group1",
    items: {
        key1: {
            description: 'i1',
            values: {
                default: 'b',
                north: 'n',
                badValue: 'badValue' // this doesn't throw an error
            }
        },

自动填充也不适用于北部,南部等。

我猜它允许的原因是createGroup函数中的扩展泛型。有没有更好的方法来编写此函数?或一种将values属性类型锁定为仅允许Direction

中的键的方法

TS游乐场Link

中的完整示例

0 个答案:

没有答案