首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Typescript动态创建界面

Typescript动态创建界面
EN

Stack Overflow用户
提问于 2017-08-19 20:03:48
回答 2查看 26.2K关注 0票数 22

我使用simple-schema在对象中定义DB模式:

代码语言:javascript
复制
{
   name: 'string',
   age: 'integer',
   ...
}

有没有可能从这个对象创建一个接口或类,这样我就不需要输入两次了?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-08-20 08:49:06

您可以这样做,但它可能会带来更多的麻烦,除非您认为您可能要更改模式。TypeScript没有以您想要的方式推断类型的内置方法,因此您必须诱使它这样做:

首先,定义一种将文字名称'string''integer'映射到它们表示的TypeScript类型(假设分别是stringnumber )的方法:

代码语言:javascript
复制
type MapSchemaTypes = {
  string: string;
  integer: number;
  // others?
}

type MapSchema<T extends Record<string, keyof MapSchemaTypes>> = {
  -readonly [K in keyof T]: MapSchemaTypes[T[K]]
}

现在,如果您可以获得一个与您指定的模式对象类似的适当类型的模式对象,并从中获得相关的类型:

代码语言:javascript
复制
const personSchema = {name: 'string', age: 'integer'}; 
type Person = MapSchema<typeof personSchema>; // ERROR

哦,问题是personSchema被推断为{name: string; age: string},而不是所需的{name: 'string'; age: 'integer'}。你可以用一个类型注解来解决这个问题:

代码语言:javascript
复制
const personSchema: { name: 'string', age: 'integer' } = { name: 'string', age: 'integer' }; 
type Person = MapSchema<typeof personSchema>; // {name: string; age: number};

但现在感觉你是在重复你自己。幸运的是,有一种方法可以迫使它推断出正确的类型:

代码语言:javascript
复制
function asSchema<T extends Record<string, keyof MapSchemaTypes>>(t: T): T {
  return t;
}
const personSchema = asSchema({ name: 'string', age: 'integer' }); // right type now
type Person = MapSchema<typeof personSchema>; // {name: string; age: number};

更新2020-06:在更新的TS版本中,您可以使用const assertion来获得相同的结果:

代码语言:javascript
复制
const personSchema = { name: 'string', age: 'integer' } as const;
type Person = MapSchema<typeof personSchema>;

这是可行的!

在动作on the Typescript Playground中查看它。希望这能有所帮助;祝你好运!

票数 41
EN

Stack Overflow用户

发布于 2017-08-19 22:11:17

我不认为你可以声明动态接口。但是,您可以为具有已知特性的对象创建type

您可以创建一个对象,将字符串文字映射到实际类型,例如'integer' => number,但这与问题无关。我不知道您使用的是什么框架,但下面的示例适用于一个类似的框架: Mongoose。

users.js

代码语言:javascript
复制
export const UserSchema = mongoose.Schema({
    name: String,
    value: Number
});

export const Users = mongoose.Model('users', UserSchema);

export type User = { [K in keyof typeof UserSchema]: any } ;

用法:

代码语言:javascript
复制
import { User, Users } from './user';

Users.find({}).exec((err: Error, res: User) => { ... })

返回的结果应该与UserSchema具有相同的键,但所有值都映射到any,因为您仍然需要将字符串文字映射到类型。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45771307

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档