我使用simple-schema在对象中定义数据库架构:
{
name: 'string',
age: 'integer',
...
}
有没有办法从这个对象创建一个接口或类,这样我就不必重复输入所有的内容了?
{
name: 'string',
age: 'integer',
...
}
有没有办法从这个对象创建一个接口或类,这样我就不必重复输入所有的内容了?
type MapSchemaTypes = {
string: string;
integer: number;
// others?
}
type MapSchema<T extends Record<string, keyof MapSchemaTypes>> = {
-readonly [K in keyof T]: MapSchemaTypes[T[K]]
}
现在,如果您可以获取一个适当类型的模式对象,比如您指定的那个,并从中获取关联的类型:
const personSchema = {name: 'string', age: 'integer'};
type Person = MapSchema<typeof personSchema>; // ERROR
糟糕,问题在于personSchema
被推断为{name: string; age: string}
而不是期望的{name: 'string'; age: 'integer'}
。您可以使用类型注释来解决这个问题:
const personSchema: { name: 'string', age: 'integer' } = { name: 'string', age: 'integer' };
type Person = MapSchema<typeof personSchema>; // {name: string; age: number};
但现在感觉你在重复自己。幸运的是,有一种方法可以强制它推断出正确的类型:
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
断言 来获得相同的结果:
const personSchema = { name: 'string', age: 'integer' } as const;
type Person = MapSchema<typeof personSchema>;
可以正常使用!
在Typescript Playground上看到它的效果。希望这有所帮助,祝你好运!
'integer' => number
,但这与问题无关。我不知道您使用的框架是什么,但以下示例适用于外观类似的框架:Mongoose。
users.js
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 } ;
import { User, Users } from './user';
Users.find({}).exec((err: Error, res: User) => { ... })
UserSchema
具有相同的键,但所有值都映射到任何值,因为您仍然需要将字符串字面量映射到类型。User
)包含 JavaScript 对象(UserSchema
)的 每个 键? - Devin Rhode{ [K in keyof Thing]: string }
语法,因为我想断言我的“模式”的每个键都强制为创建的类型 - 这里我能够回答自己的问题:https://stackoverflow.com/questions/64778252/create-typescript-interface-based-on-a-const-defaultvalues-map/64778253#64778253 - Devin Rhode
const personObj = { name: 'string', age: 'integer' } type Person = MapSchema;
我一直很难封装它。 - Felipe Müller