【问题标题】:Class type parameter based on subset of constructor parameters基于构造函数参数子集的类类型参数
【发布时间】:2021-10-11 18:19:40
【问题描述】:

我有一个有类型参数的类,C:

import { EventEmitter } from "events";

interface ClientData {
    a: string;
    b?: string;
}

interface ClientOptions {
    b?: string;
}

class Client<C extends ClientData> extends EventEmitter {

    constructor(clientData: C) {

        super();

        console.log(clientData.a); // string
        console.log(clientData.b); // string | undefined
    }
}

const client = new Client({
    a: "example",
    b: "placeholder"
});

/**
 * Client<{
 *    a: string;
 *    b: string;
 *}>
 */
type ClientType = typeof client;

该类的构造函数采用ClientData 类型的参数,其中输入的类型变为C 类型参数。正如ClientType 所见,这工作正常。

但是,我需要C 类型只包含ClientData 的属性子集,在本例中为ClientOptions,并且它需要具有{} 的默认值:

class Client<C extends ClientOptions = {}> extends EventEmitter {

    constructor(clientData: C) {

        super();

        console.log(clientData.a); // Property 'a' does not exist on type 'C'
        console.log(clientData.b); // string | undefined
    }
}

这里的问题是构造函数中的clientData 参数将不再具有ClientData 中的a 属性。由于构造函数不能有类型参数,我怎么能让clientDataClientData 类型,但还要确保C 类型扩展ClientOptions,默认为{}ClientOptions 的所有属性都是可选的,并且存在于 ClientData 中。

【问题讨论】:

    标签: javascript typescript types generic-type-parameters


    【解决方案1】:

    使用Partial 使属性可选:

    class Client<C extends Partial<ClientData>> extends EventEmitter {
    
        constructor(clientData: C) {
    
            super();
    
            console.log(clientData.a); // string
            console.log(clientData.b); // string | undefined
        }
    }
    

    【讨论】:

    • 这似乎使ab 都是可选的,我需要a 成为必需的字符串
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-12-05
    • 2012-09-22
    • 1970-01-01
    • 1970-01-01
    • 2015-05-21
    • 2017-09-14
    • 1970-01-01
    相关资源
    最近更新 更多