国产日韩精品视频_2020久久国产最新免费观看_国内久久久久影院精品_日本一区二区视频在线

使用帶有特定字段的typescript創建類

我想創建一個相當靈活的類,名為Model,如:

export class Model {
    _required_fields: Array<string> = [];
    _optional_fields?: Array<string> = [];

    constructor(params: Dictionary<string> = {}) {
        // make sure all required fields are in the params obj
    }

    set(params: Dictionary<string>){
        // make sure only required or optional fields are present

        this.all_fields.forEach(key => {
            this[key] = params[key];
        });
    }

    get all_fields(): Array<string> {
        return [...this._required_fields,...this._optional_fields];
    }

    get required_fields() {
        return this._required_fields;
    }
}

這個函數的子函數將定義必填字段和可選字段,我將其縮短,因為我在set方法中進行了一些錯誤檢查。例如:

export class User extends Model {
    static REQUIRED_FIELDS = ['username'];
    static OPTIONAL_FIELDS = ['email'];

    get required_fields() {
        return (this._required_fields?.length==0) ? User.REQUIRED_FIELDS : [];
    }

    static get ALL_FIELDS() {
        return [...User.REQUIRED_FIELDS, ...User.OPTIONAL_FIELDS];
    }

    constructor(params: Dictionary<string> = {}) {
      super(params);
    }
}

我有一個User版本,其中包含以下字段:

username: string;
email: string;

但是我希望能夠定義字段,以便set函數可以接受一個Dictionary并填充字段,如圖所示。

我在以下行中得到了類型腳本錯誤No index signature with a parameter of type 'string' was found on type 'Model'.

this[key] = params[key];

我意識到這一點,因為我需要在Model的內部定義一個類似:[key: string]: string;的字段。

這似乎有兩種可能性:

方法1:在User的內部,定義每個字段,并在set(ofUser)的內部顯式執行

user.username = params.username;
user.email = params.email;

然而,我必須對模型的所有子級重復這一點,我有一些錯誤檢查,我想自動化一點。

方法2:或者,我可以保持模型具有泛型字段

[key: string]: string;

然后set將按原樣工作,但沒有能力執行user.username,但可以執行user['username']

summary

到目前為止,我已經完成了方法1,并且有大量重復的代碼,因為我需要為Model的每個子級顯式地完成所有字段。(實際上,我有兩個以上的字段)。這并不令人滿意,似乎我可以在Model類中編寫更緊湊的內容,而不是每個孩子。

方法2似乎繞過了typescript的許多強類型,因此,盡管代碼更緊湊,但似乎并不太好。

Question

我有沒有辦法將typescript的強類型與方法1的靈活性結合起來

? 最佳回答:

看起來您希望Model保持跟蹤requiredFieldsoptionalFields元素中的實際文字值,這意味著Model在這些類型中可能是泛型的。所以可能類似于Model<R, O>,其中R是所有必需鍵的并集,O是所有可選鍵的并集。

但是您還希望Model<R, O>實際具有RO類型的鍵。這就是我們在使用常規的class語句時遇到麻煩的地方。類和接口要求編譯器靜態地知道它們的鍵。它們不能是動態的,不能在以后填寫:

class Foo<T extends object > implements T {} // error!
// -----------------------------------> ~
// A class can only implement an object type or intersection 
// of object types with statically known members.

所以我們需要解決這個問題。


描述這樣的類構造函數類型很容易。應該是這樣的

type ModelConstructor = new <R extends string, O extends string>(
    params: ModelObject<R, O>
) => ModelObject<R, O> & {
    set(params: Partial<ModelObject<R, O>>): void,
    all_fields: Array<R | O>;
    required_fields: R[];
}

type ModelObject<R extends string, O extends string> =
    Record<R, string> & Partial<Record<O, string>>;

因此,ModelConstructor有一個構造簽名,它接受類型為ModelObject<R, O>paramsModelObject<R, O>是一種對象類型,具有必需的鍵R和可選鍵O,其值均為string。構造的實例也是一個ModelObject<R, O>,它與Model類中的一組適當類型的屬性和方法相交。

不過,在繼續討論這個問題之前,考慮一下如何將Model子類化可能會很有用。由于您希望User的每個實例都具有相同的必填字段和可選字段,因此將Model設置為類工廠函數而不是class構造函數本身可能是有意義的。否則,您需要冗余地指定RO

class AnnoyingUser extends Model<"username", "email"> {
    _required_fields = ["username"] // redundant
    _optional_fields = ["email"] // redundant
}

寫下來可能會更好

class User extends Model(["username"], ["email"]) { }

其中Model(["username"], ["email"])生成一個類構造函數,其中這些字段已經存在。這取決于你是否想這樣做。我將假設工廠函數是可以接受的,并繼續使用它。


這里是工廠函數:

export const Model = <R extends string, O extends string>(
    requiredFields: R[], optionalFields: O[]
) => {

    type ModelObject =
        Record<R, string> & Partial<Record<O, string>> extends
        infer T ? { [K in keyof T]: T[K] } : never;

    class _Model {
        _required_fields: Array<R> = requiredFields;
        _optional_fields?: Array<O> = optionalFields;

        constructor(params: ModelObject) {
            this.set(params);
        }

        set(params: Partial<ModelObject>) {
            this.all_fields.forEach(key => {
                (this as any)[key] = (params as any)[key];
            });
        }

        get all_fields(): Array<R | O> {
            return [...this._required_fields,
            ...this._optional_fields ?? []];
        }

        get required_fields() {
            return this._required_fields;
        }
    }

    return _Model as any as new (params: ModelObject) =>
        ModelObject & {
            set(params: Partial<ModelObject>): void,
            all_fields: Array<R | O>;
            required_fields: R[];
        } extends infer T ? { [K in keyof T]: T[K] } : never;
}

注意,從Model返回的類構造函數關閉傳遞給它的requiredFieldsoptionalFields變量。

這些類型與以前類似,只是RO現在是工廠函數上的泛型類型參數,而不是結果類。作用域略有不同,因此(例如)ModelObject不需要在RO中是泛型的,因為RO在該作用域中是已知的。還有一些拋出的extends infer T ? {[K in keyof T]: T[K]}: never類型,它們只是要求編譯器將類似Record<"username", string> & Partial<Record<"email", string>>的東西擴展成一個更好看的{username: string; email?: string}類型。

還要注意,由于編譯器不能將class表示為具有動態屬性,因此我需要使用類型斷言來告訴編譯器它可以將返回的構造函數視為正確的類型。

一旦使用工廠函數,您就可以決定進一步重構;也許您希望必需/可選字段僅為返回的類構造函數的static屬性,因為它們對于類的每個實例都應該相同。不過我不想麻煩了。只是一個想法。


讓我們測試一下。首先讓我們看看當我們調用Model時會出現什么結果:

const UserModel = Model(["username"], ["email"]);
/* const UserModel: new (params: {
    username: string;
    email?: string | undefined;
}) => {
    username: string;
    email?: string | undefined;
    set: (params: Partial<{
        username: string;
        email?: string | undefined;
    }>) => void;
    all_fields: ("username" | "email")[];
    required_fields: "username"[];
} */

看起來很合理,我想你想要什么。現在我們可以定義User

export class User extends Model(["username"], ["email"]) {
    // static REQUIRED_FIELDS = ['username'];
    // static OPTIONAL_FIELDS = ['email'];
}

我注釋掉的那些static屬性來自您的示例,但它們不是我的解決方案所必需的。如果你想要它們,可以隨意添加,但我不知道它們有什么用途。

讓我們測試一下:

const u = new User({ username: "alice" });
console.log(u.required_fields) // ["username"]
console.log(u.all_fields) // ["username", "email"]
u.set({ email: "foo@example.com" })
console.log(u.email) // foo@example.com

Looks good!

操場連結至守則

国产日韩精品视频_2020久久国产最新免费观看_国内久久久久影院精品_日本一区二区视频在线

一区二区三区三区在线| 99精品欧美一区二区三区综合在线| 激情久久五月天| 99re6这里只有精品| 亚洲欧美在线看| 欧美欧美天天天天操| 国产日韩欧美在线播放| 亚洲精品久久久久久下一站| 欧美在线一区二区三区| 欧美日韩妖精视频| 欧美午夜片在线观看| 影音先锋日韩资源| 欧美一区二区日韩一区二区| 欧美精品一区在线发布| 激情91久久| 午夜精品久久久久久久久久久久| 欧美gay视频| 国产精品日韩欧美综合| 亚洲高清视频一区| 久久亚洲一区二区三区四区| 黄色成人av| 噜噜噜噜噜久久久久久91| 国内自拍视频一区二区三区| 久久av一区二区三区漫画| 国产精品看片你懂得| 亚洲综合电影| 国产精品视频一| 性欧美1819性猛交| 国产亚洲综合在线| 麻豆精品传媒视频| 亚洲精品国产欧美| 欧美午夜一区| 久久精品首页| 亚洲激情在线观看视频免费| 欧美大片一区二区| 一区二区国产日产| 国产精品国产亚洲精品看不卡15| 麻豆av一区二区三区久久| 在线观看欧美日本| 欧美福利电影在线观看| 99精品视频一区| 国产麻豆精品视频| 久久亚洲捆绑美女| 亚洲人成亚洲人成在线观看图片 | 久久精品国产免费看久久精品| 国产亚洲精品一区二区| 麻豆成人综合网| 一区二区三区国产在线| 国产日韩精品在线观看| 久久香蕉国产线看观看av| 亚洲靠逼com| 国产日韩欧美在线| 欧美大片免费| 香蕉精品999视频一区二区| 韩曰欧美视频免费观看| 欧美人妖另类| 久久婷婷av| 亚洲一区二区三区在线看| 伊大人香蕉综合8在线视| 国产精品99一区二区| 狂野欧美性猛交xxxx巴西| 亚洲一区二区三区四区在线观看 | 性8sex亚洲区入口| 亚洲电影在线看| 国产精品久久久久一区二区三区| 久久婷婷国产综合国色天香| 亚洲视频一区| 亚洲第一黄色网| 国产亚洲精品久| 欧美视频你懂的| 久久一区视频| 午夜精彩视频在线观看不卡| 国产欧美一区二区三区沐欲| 欧美人与性禽动交情品| 性做久久久久久久久| 亚洲国产精品一区二区第一页 | 久久久999精品免费| 亚洲人成人一区二区在线观看| 欧美美女bbbb| 久久精品久久99精品久久| av成人福利| 好吊日精品视频| 国产精品狠色婷| 欧美日韩在线三区| 老牛嫩草一区二区三区日本| 亚洲视频一起| 最新中文字幕亚洲| 国产一区二区福利| 欧美视频精品在线| 欧美岛国激情| 久久精品99国产精品| 欧美在线视频播放| 在线视频精品一区| 91久久精品国产| 国产乱码精品一区二区三区五月婷 | 久久久精品日韩欧美| 亚洲影院高清在线| 日韩视频不卡| 91久久亚洲| 在线观看欧美日本| 亚洲国产成人精品久久| 国产真实久久| 国产欧美日韩一区| 国产精品视频一二| 欧美午夜不卡影院在线观看完整版免费| 免费亚洲网站| 久久伊人精品天天| 久久人91精品久久久久久不卡| 久久久久久久波多野高潮日日 | 亚洲欧美资源在线| 亚洲一区二区三区免费观看| 亚洲伦理久久| 99热在这里有精品免费| 亚洲欧洲一区二区在线播放| 在线观看中文字幕不卡| 黄色一区二区在线| 国产日韩欧美不卡在线| 国产精品毛片在线看| 国产精品久久激情| 欧美日韩国产一区二区| 欧美国产视频在线| 欧美激情一区二区三区四区| 欧美高清影院| 欧美日韩伦理在线| 欧美极品欧美精品欧美视频| 欧美体内she精视频在线观看| 国产精品久久久999| 国产精品午夜av在线| 国产午夜久久| 在线观看成人网| 亚洲精品久久久久久久久久久| 日韩午夜激情| 亚洲一区国产| 久久精品一二三| 欧美国产第一页| 国产精品a级| 国产一区二区精品丝袜| 亚洲第一二三四五区| 亚洲欧洲日产国产综合网| 亚洲精品视频在线| 亚洲午夜未删减在线观看| 欧美亚洲免费在线| 蜜桃伊人久久| 欧美色一级片| 欧美日韩国产在线播放| 国精品一区二区三区| 亚洲国产成人在线视频| 亚洲图片在线| 久久青草久久| 国产精品vip| 黑丝一区二区三区| 亚洲一区二区成人在线观看| 久久国产欧美日韩精品| 欧美精品亚洲精品| 国内精品久久久久影院薰衣草| 91久久午夜| 欧美专区中文字幕| 欧美网站大全在线观看| 国产视频观看一区| 一区二区三区导航| 老牛影视一区二区三区| 欧美日韩综合网| 亚洲美女av黄| 久久久久免费| 国产精品久久久一区麻豆最新章节| 1024亚洲| 性色av一区二区三区红粉影视| 欧美午夜精品理论片a级按摩| 极品av少妇一区二区| 亚洲影院免费观看| 另类欧美日韩国产在线| 国产亚洲精品久久久久久| 99天天综合性| 欧美第一黄色网| 亚洲黄页一区| 麻豆国产精品777777在线| 国产永久精品大片wwwapp| 亚洲一区二区三区在线观看视频| 久久精品国产一区二区三区免费看 | 久久久久www| 国产欧美日韩一区二区三区在线| 亚洲麻豆国产自偷在线| 免费看精品久久片| 黄色国产精品| 久久久久国产精品一区二区| 国产欧美日韩三级| 亚洲午夜视频| 欧美视频在线一区二区三区| 亚洲乱码国产乱码精品精 | 欧美诱惑福利视频| 国产精品青草综合久久久久99| 一本色道综合亚洲| 欧美日韩1区2区3区| 亚洲国产精品成人精品| 久久久久亚洲综合| 黄色亚洲精品| 久久夜色精品国产亚洲aⅴ| 伊人色综合久久天天| 男女激情久久| 在线观看成人小视频|