javascript - 基于泛型类型定义 TypeScript 类型
问题描述
让我们data
在 TypeScript (4.0.5) 中使用 JSON 类型的列和这个枚举的 SQL 数据库表:
enum EContentType {
NOTHING,
IMAGE,
VIDEO
}
根据ContentType
我将不同的 JSON 模式保存data
到我的数据库的列中。
例子:
- 对于
IMAGE
, 节省{"path": "/foo/bar", "type": "jpeg"}
- 对于
VIDEO
, 节省{"path": "/foo/bar", "length": 60}
是否可以使用泛型为该data
对象创建 TypeScript 类型,该类型将基于什么来正确键入EContentType
?
像(伪)这样的东西:
type TDataType<ContentType> = {
[ContentType.IMAGE]: {path: string, type: string}
[ContentType.VIDEO]: {path: string, length: number}
}
用法:
const concreteType: EContentType = EcontentType.IMAGE;
const typedDataField = dataField as TDataType<concreteType>;
这可能吗?或者不是,因为 TypeScript 只是静态类型的......有什么不同的想法如何保证类型安全(不允许有人length
为内容类型保存属性IMAGE
)?
如果没有办法做到这一点,那么键入什么会像这样工作:
const data1 = dbDataField as TDataType<EContentType.IMAGE> // {path: string, type: string}
const data2 = dbDataField as TDataType<EContentType.VIDEO> // {path: string, length: number}
解决方案
这不起作用,因为您将其声明ContentType
为类型但将其用作值。一个更好的方法是使用一个接口和extends
你想要的任何你想要预定义的泛型属性
interface TDataType <T>{
[key: string]: T
}
let a: TDataType<{path: string, type: string}>;
a.IMAGE = {path: 'aaa', type: 'bbbb'};
console.log(a); // output: "IMAGE": {"path": "aaa", "type": "bbbb"}
或使用Record<Keys, type>
实用程序类型来定义https://www.typescriptlang.org/docs/handbook/utility-types.html#recordkeystype
interface Content{
path: string, type: string
}
type ContentType = "IMAGE" | "VIDEO";
const concreteType: Record<ContentType , Content> = {
IMAGE: { path: "", type: ""}
};
推荐阅读
- google-apps-script - 如何使用脚本谷歌表计算单元格中分号之间的字符串数量
- javascript - 从 Webpack bundle.js 获取/导入 bootstrap.js
- rust - 如何在 Parity Substrate 自定义运行时中使用泛型结构?
- .net-core - 如何在 yocto-build 中包含正确的 libssl 版本以运行 .net-core 应用程序?
- sulu - Sulu 1.6:自定义模板的实时预览不起作用
- reactjs - 无法从“.ts”文件导入“.tsx”文件
- java - Gradle 如何使用内部配置文件创建外部文件夹配置?
- ios - Firebase 身份验证使用相同的电子邮件登录多个提供商
- java - 用于匹配 ArrayList 中的日期的公历对象
- .net - Matlab 2017a -> 2018b。访问.NET 程序集不同?