簡體   English   中英

打字稿動態創建界面

[英]Typescript dynamically create interface

我使用簡單模式在對象中定義數據庫模式:

{
   name: 'string',
   age: 'integer',
   ...
}

是否有可能從這個對象創建一個接口或類,所以我不必兩次輸入所有內容?

您可以這樣做,但它可能比它的價值更麻煩,除非您認為您可能正在更改架構。 TypeScript 沒有以您想要的方式推斷類型的內置方法,因此您必須哄騙它這樣做:


首先,定義一種將文字名稱'string''integer'映射到它們所代表的 TypeScript 類型(大概分別是stringnumber )的方法:

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: string}而不是所需的{name: 'string'; age: 'integer'} {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。

用戶.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具有相同的鍵,但所有值都映射到 any ,因為您仍然需要將字符串文字映射到類型。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM