繁体   English   中英

来自枚举的条件打字稿函数类型

[英]Conditional Typescript function typings from enum

我正在创建一个数据库模式,它需要每个模型类型的字符串名称,我需要避免使用类。 我的数据库模型由枚举和接口定义:

const enum Models {
  Person = 'Person',
  Vehicle = 'Vehicle',
}

export interface Person {
  firstname: string;
  lastname?: string;
}

export interface Vehicle {
  model: string;
  year?: string;
}

DatabaseModel 接口链接模型类型名称和关联数据:

export interface DatabaseModel {
  modelType: any;
  data: any;
}

此类型将接口映射到特定的枚举。 我不确定如何准确地使用它,但我认为类型检查需要它才能正常工作。

export type ModelInterfaceMap = {
  Person: Person;
  Vehicle: Vehicle;
}

我创建了一个创建 DatabaseModel 的函数,如下所示:

export function create(modelType: Models, data ): DatabaseModel {
  return {
    modelType,
    data,
  };
}

我的问题是,如何向上面的代码添加类型,以便我可以调用 create 函数,并且只在第一个 modelType 参数中引用模型类型一次,并且仍然获得根据关联模型检查数据的所有好处?

这应该通过类型检查

var newPerson = create(Models.Person, { firstname: 'John', lastname: 'Doe' });
var newVehicle = create(Models.Vehicle, { model: 'Ford', year: '2018' });

这应该会失败类型检查,因为 Person 接口没有年份

var newPersonFail = create(Models.Person, { firstname: 'John', lastname: 'Doe', year: '2018' });

我尝试使用这样的泛型类型,但这需要两次编写模型类型; 一次在泛型类型中,一次在传入模型类型时。 我想避免必须两次指定 modelType。

export function create<T>(modelType: Models, data : <T> ): DatabaseModel<T> {...}

您需要在泛型类型参数(作为枚举文字类型)中捕获传递给函数的实际枚举成员。 有了这种类型,我们可以使用它来索引ModelInterfaceMap以根据传入的枚举获取data的适当类型:

export function create<T extends Models>(modelType: T, data: ModelInterfaceMap[T]): DatabaseModel {
    return {
        modelType,
        data,
    };
}

var newPerson = create(Models.Person, { firstname: 'John', lastname: 'Doe' });
var newVehicle = create(Models.Vehicle, { model: 'Ford', year: '2018' });

var newPersonFail = create(Models.Person, { firstname: 'John', lastname: 'Doe', year: '2018' });

暂无
暂无

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

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