thesayyn / protoc-gen-ts

Compile protocol buffer messages to TypeScript.
MIT License
362 stars 73 forks source link

How can I get type of message in Typescript #206

Open god-of-javascript opened 1 year ago

god-of-javascript commented 1 year ago

Image I have this message:

export class LoginRequest extends pb_1.Message {
    #one_of_decls: number[][] = [[5], [6]];
    constructor(data?: any[] | ({
        email?: string;
        password?: string;
        invite_token?: string;
        location_time?: number;
    } & (({
        ip_address?: string;
    }) | ({
        local_time_zone?: string;
    })))) {
        super();
        pb_1.Message.initialize(this, Array.isArray(data) ? data : [], 0, -1, [], this.#one_of_decls);
        if (!Array.isArray(data) && typeof data == "object") {
            if ("email" in data && data.email != undefined) {
                this.email = data.email;
            }
            if ("password" in data && data.password != undefined) {
                this.password = data.password;
            }
            if ("invite_token" in data && data.invite_token != undefined) {
                this.invite_token = data.invite_token;
            }
            if ("location_time" in data && data.location_time != undefined) {
                this.location_time = data.location_time;
            }
            if ("ip_address" in data && data.ip_address != undefined) {
                this.ip_address = data.ip_address;
            }
            if ("local_time_zone" in data && data.local_time_zone != undefined) {
                this.local_time_zone = data.local_time_zone;
            }
        }
    }
    get email() {
        return pb_1.Message.getFieldWithDefault(this, 1, "") as string;
    }
    set email(value: string) {
        pb_1.Message.setField(this, 1, value);
    }
    get password() {
        return pb_1.Message.getFieldWithDefault(this, 2, "") as string;
    }
    set password(value: string) {
        pb_1.Message.setField(this, 2, value);
    }
    get invite_token() {
        return pb_1.Message.getFieldWithDefault(this, 3, "") as string;
    }
    set invite_token(value: string) {
        pb_1.Message.setField(this, 3, value);
    }
    get location_time() {
        return pb_1.Message.getFieldWithDefault(this, 4, 0) as number;
    }
    set location_time(value: number) {
        pb_1.Message.setField(this, 4, value);
    }
    get ip_address() {
        return pb_1.Message.getFieldWithDefault(this, 5, "") as string;
    }
    set ip_address(value: string) {
        pb_1.Message.setOneofField(this, 5, this.#one_of_decls[0], value);
    }
    get has_ip_address() {
        return pb_1.Message.getField(this, 5) != null;
    }
    get local_time_zone() {
        return pb_1.Message.getFieldWithDefault(this, 6, "") as string;
    }
    set local_time_zone(value: string) {
        pb_1.Message.setOneofField(this, 6, this.#one_of_decls[1], value);
    }
    get has_local_time_zone() {
        return pb_1.Message.getField(this, 6) != null;
    }
    get _ip_address() {
        const cases: {
            [index: number]: "none" | "ip_address";
        } = {
            0: "none",
            5: "ip_address"
        };
        return cases[pb_1.Message.computeOneofCase(this, [5])];
    }
    get _local_time_zone() {
        const cases: {
            [index: number]: "none" | "local_time_zone";
        } = {
            0: "none",
            6: "local_time_zone"
        };
        return cases[pb_1.Message.computeOneofCase(this, [6])];
    }
    static fromObject(data: {
        email?: string;
        password?: string;
        invite_token?: string;
        location_time?: number;
        ip_address?: string;
        local_time_zone?: string;
    }): LoginRequest {
        const message = new LoginRequest({});
        if (data.email != null) {
            message.email = data.email;
        }
        if (data.password != null) {
            message.password = data.password;
        }
        if (data.invite_token != null) {
            message.invite_token = data.invite_token;
        }
        if (data.location_time != null) {
            message.location_time = data.location_time;
        }
        if (data.ip_address != null) {
            message.ip_address = data.ip_address;
        }
        if (data.local_time_zone != null) {
            message.local_time_zone = data.local_time_zone;
        }
        return message;
    }
    toObject() {
        const data: {
            email?: string;
            password?: string;
            invite_token?: string;
            location_time?: number;
            ip_address?: string;
            local_time_zone?: string;
        } = {};
        if (this.email != null) {
            data.email = this.email;
        }
        if (this.password != null) {
            data.password = this.password;
        }
        if (this.invite_token != null) {
            data.invite_token = this.invite_token;
        }
        if (this.location_time != null) {
            data.location_time = this.location_time;
        }
        if (this.ip_address != null) {
            data.ip_address = this.ip_address;
        }
        if (this.local_time_zone != null) {
            data.local_time_zone = this.local_time_zone;
        }
        return data;
    }
    serialize(): Uint8Array;
    serialize(w: pb_1.BinaryWriter): void;
    serialize(w?: pb_1.BinaryWriter): Uint8Array | void {
        const writer = w || new pb_1.BinaryWriter();
        if (this.email.length)
            writer.writeString(1, this.email);
        if (this.password.length)
            writer.writeString(2, this.password);
        if (this.invite_token.length)
            writer.writeString(3, this.invite_token);
        if (this.location_time != 0)
            writer.writeInt32(4, this.location_time);
        if (this.has_ip_address)
            writer.writeString(5, this.ip_address);
        if (this.has_local_time_zone)
            writer.writeString(6, this.local_time_zone);
        if (!w)
            return writer.getResultBuffer();
    }
    static deserialize(bytes: Uint8Array | pb_1.BinaryReader): LoginRequest {
        const reader = bytes instanceof pb_1.BinaryReader ? bytes : new pb_1.BinaryReader(bytes), message = new LoginRequest();
        while (reader.nextField()) {
            if (reader.isEndGroup())
                break;
            switch (reader.getFieldNumber()) {
                case 1:
                    message.email = reader.readString();
                    break;
                case 2:
                    message.password = reader.readString();
                    break;
                case 3:
                    message.invite_token = reader.readString();
                    break;
                case 4:
                    message.location_time = reader.readInt32();
                    break;
                case 5:
                    message.ip_address = reader.readString();
                    break;
                case 6:
                    message.local_time_zone = reader.readString();
                    break;
                default: reader.skipField();
            }
        }
        return message;
    }
    serializeBinary(): Uint8Array {
        return this.serialize();
    }
    static deserializeBinary(bytes: Uint8Array): LoginRequest {
        return LoginRequest.deserialize(bytes);
    }
}

How can I get the type of LoginRequest? I tried typeof but it doesn't work!

god-of-javascript commented 1 year ago

I figured out that we can do:

ReturnType<typeof CLASS.prototype.toObject>

or

const instance = new CLASS().toObject();
type YourType = typeof instance;

it was better to export this with the generated files

god-of-javascript commented 1 year ago

I have created this generic type to get class type!

/**
 * Get type of proto class
 */
export type GetTypeOf<T> = ReturnType<InstanceType<T>["toObject"]>;

const a:GetTypeOf<typeof Class> = {
   // type safe object
}