在TypeScript中将用户定义的对象用作类型

在这种情况下,我不知道类型是什么样,无论是未定义的还是布尔值,字符串或数字等。我正在研究一个解析某些字符串内容并返回的库用户使用“类型对象”描述的属性对象。

res = http.request('GET',download_url,preload_content=False) out_file = open(out_file,'wb') shutil.copyfileobj(res,out_file) 是类型对象外观的接口,它像这样:

Type

我已经为用户提供了3个预定义的“类型对象”,它们遵循此界面(数字作为numberType,布尔作为booleanType,字符串作为stringType)。用户可以使用这些类型从字符串中收集参数。

参数接口定义应如何在代码中指定参数。

/**
 * A type object.
 */
export default interface IType<O>
{
    /** The name of the type. */
    name: string;

    /** A description of the type. */
    description?: string;

    /**
     * Parse the given input content and return the parsed output value.
     * @param input The given input value.
     * @returns The parsed output.
     */
    parse(input: string): O;
}

用户创建命令类,并将一些参数传递给构造函数,包括参数数组;

/**
 * An object describing how an argument will look like.
 */
export default interface IArg<T>
{
    /**
     * The name of the argument,this is how you use the argument later
     * in the command object.
     */
    name: string;

    /** A description about the argument. */
    description?: string;

    /** The type the argument should be resolved with. */
    type: IType<T>;

    /** Should this take all the parameters left of the string? */
    rest?: boolean;

    /** Is the argument required? */
    required?: boolean;
}

解析命令字符串时,这些参数将添加到对象[ { name: "age" type: numberType },{ name: "name",type: stringType } ] 中。我想以某种方式让打字稿解析器知道用户提供的信息可能会或可能不会提供什么。

例如如果参数是必需的并且是input.args的类型(我们将其称为IArg<string>),则解析器会知道name绝对是字符串,但是如果不需要,则可能是未定义的或字符串。

这有可能实现吗?

  

编辑:我发现了thisjcalz答案,该答案带有一个键值对对象,该对象正是我所要寻找的;但是我不确定如何使用数组来实现它。

wang312627 回答:在TypeScript中将用户定义的对象用作类型

这是我想出的:

首先从接口定义中删除required参数。其原因很快将变得显而易见:

interface IArg<T> {
    /**
     * The name of the argument,this is how you use the argument later
     * in the command object.
     */
    name: string;

    /** A description about the argument. */
    description?: string;

    /** The type the argument should be resolved with. */
    argType: IType<T>;

    /** Should this take all the parameters left of the string? */
    rest?: boolean;
};

现在,我使用这个人为设计的 token解析器示例,该示例应该仅在令牌是必需的或可用的情况下(即不为null)解析令牌。

// Used to check if the IArg has a required parameter that is set to true
function argIsRequired(arg: IArg<unknown> & {required?: boolean}): boolean {
    return arg.required === true;
}

function parseToken<T>(token: string,decodeToken: IArg<T> & { required: true }): T;
function parseToken<T>(token: string,decodeToken: IArg<T>): T | undefined;
function parseToken<T>(token: string | null,decodeToken: IArg<T>) {
    if (token == null) {
        if (argIsRequired(decodeToken)) {
            throw Error("required token not found");
        } else {
            return undefined;
        }
    }
    return decodeToken.argType.parse(token);
}

函数重载的目的是帮助类型检查器确定是否允许某些返回类型(TT | undefined)。

通过从required接口中删除IArg参数,我们现在可以将其专用于解析器函数以充当该函数的类型防护。

现在要测试,我们定义了两个可能的参数,其中一个是必需的,而另一个则不是:

const ageArg = new class implements IArg<number> {
    readonly name = "age"
    readonly argType = numberType;
    readonly required = true;
};

const nameArg = new class implements IArg<string> {
    readonly name = "name"
    readonly argType = stringType;
};

如果上面的定义正确,那么如果我们为上面的parseToken函数返回的值尝试使用错误的类型,则类型检查器应该给我们一个错误。

const age: number = parseToken('24',ageArg); // This is Ok
// const name: string = parseToken("",nameArg); // This gives error
const name: string | undefined = parseToken("",nameArg); // This is Ok

Playground link

,

经过大量的修改,我最终没有找到如何做的方法。 “程序员的环聊”不和谐服务器上的一些天才们花了大约10分钟的时间,借助我添加到帖子中的SO链接以及他一些精明的思想,解决了这个问题!

https://www.typescriptlang.org/play/index.html?ssl=1&ssc=1&pln=33&pc=1#code/C4TwDgpgBAggTgcygXigbynCBDAJgewDsAbEKQ7AWwgC4oBnYOAS0IQBpMcCSzRI6jFm05Y8RUlwCOAV2ZZcAfjoAjfPmI5CUAL4BuAFAGAxkUZRKIeAnoooAbQNRn6clVpQARADN5jAHLunpz8Hp5CrAjB0nIKdEwy0DrsTi4YFNR0ntgIENGhWYQylCoQcJ66BgC6UNi2poSMhgaswGXe2MbQACrgEACy2GDoqUUlZXRjpXCGzmoaWqrqmtiEs1AyhLgQvoQQuHSb27v76xFsgkyR6-gqAFYQxsB0tw9PUAA+5DLExIY6RlCUAA8vdHsAAGJwfCUAAiEHoxhYYGA+DgAB5ulAIAAPNpbWzWAB8qWcqG69k8GTyNVx+NwtnOCFJUEUUApnlCnlpeIgBKgAGsICB8N52X1BmAWWyOVhZPJ9tzsbz+QkINLXPYANJQVjsynU7lVOi9SCS+wcrlVGoAlxQOgYbW67Qcw3W5Tis1DC2Uq02lmTCAANzKAfIwbKzSBsOYERUMja6IAqsr6YTEES7Cm6XyGbBEKyQWCnlCYfDEcjURik5nAyGZoC+lAk4RmERuvgAJKENpwejgtuEZOZ1CpAAU2ZVedWZDZY4FdCTAEoUJmg-hmLh7eH6yuc-yx-O6KxvGUoJ2V8g1xvcCu2Z3t3t643IFAABpZ1vtrs9sr9p6DuiMZxgmEDomOoSihYViIPQS72FMZRVESRLNJowBQDidAfqgGC+H2wCBJkXgAFL4AAFoQ0Q5B4ABMACsuiGEAA

本文链接:https://www.f2er.com/3060530.html

大家都在问