[英]Make Typescript infer types from a plain javascript object
I do not know if this is at all possible, so sorry in advance for the potentially stupid question, but here's my problem.我不知道这是否可能,所以提前为这个可能很愚蠢的问题感到抱歉,但这是我的问题。
I'm creating a library where a user can provide a database schema like so:我正在创建一个库,用户可以在其中提供这样的数据库架构:
const personSchema: Schema = {
name: 'person',
properties: [
{ name: 'firstName', type: 'string', primary: true, required: true },
{ name: 'age', type: 'number', required: false }
]
}
Later, when using one of the library's functions, I'd like to be able to do something like this:后来,当使用库的功能之一时,我希望能够做这样的事情:
db.get(12).firstName; // no error
db.get(12).test; // compile error when in TS or (at least) no intellisense when in JS
And get full intellisense with this.并获得完整的智能感知。
The library itself will be written in typescript whereas the user can use either javascript or typescript.库本身将用打字稿编写,而用户可以使用 javascript 或打字稿。 When using typescript, they will be able to do something like
const personCollection = new Collection<Person>();
使用打字稿时,他们将能够执行诸如
const personCollection = new Collection<Person>();
, but in Javascript they'll only provide a Schema
object. ,但在 Javascript 中,它们只会提供一个
Schema
对象。
Is this at all possible?这是可能吗? I know that at least VSCode gives some type hinting while writing javascript, but I've never seen something this "advanced";
我知道至少 VSCode 在编写 javascript 时会给出一些类型提示,但我从未见过这种“高级”的东西; inferring types from an object that defines its types using strings.
从使用字符串定义其类型的对象推断类型。
I think there is no way to infer a type ( get()
return type) from an Object's properties values which is by definition something existing only at runtime.我认为没有办法从对象的属性值推断类型(
get()
返回类型),根据定义,该值仅在运行时存在。
What I would do instead is to allow your user to create a specific string literal for his Schema's properties names, something like this:我会做的是允许您的用户为其架构的属性名称创建特定的字符串文字,如下所示:
interface Schema<T> {
name: string;
properties: {
name: T;
type: "string" | "number";
primary?: boolean;
required: boolean;
}[];
}
type PersonProperties = "firstName" | "lastName" | "age";
type PersonSchema = Schema<PersonProperties>;
const personSchema: PersonSchema = {
name: "person",
properties: [
{ name: "firstName", type: "string", primary: true, required: true },
{ name: "age", type: "number", required: false }
]
};
const get = function<T>(): T {
// ...
return null;
};
const person1 = get<PersonSchema>();
person1.properties[0].name === "firstName"; // name is infered to one of the 3 PersonProperties
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.