Typescript Fluent API - 从每个函数的返回值中省略函数

问题描述

此问题建立在问题和已接受答案 in this link 的基础上。

我想编写一个表单生成器类,其中使用底层类型 T 来确定可以调用哪些函数。举个例子,假设这是我们想要一个表单的模型:

interface MyFormModel {
    name: string;
    options: number[];
    isPrimary: boolean;
    address: {
        street: string;
        houseNumber: number;
        someArrayThatsRelevantToAddresses: string[];
    }
}

我希望能够为属性 'isPrimary' 创建一个复选框,然后我希望 this 的返回值不包括用于创建复选框的方法,因为没有更多的布尔值剩下的属性可以调用“createCheckBox”。我使用第二个类型参数 K 跟踪哪些属性已经用完。每次使用来自 T 的键调用函数后,K 都会更新,以便我们跟踪哪些键已经用完。这是我的实现:

// T is the model for the form,K will accumulate props from T as we build the form
class FormBuilder<T,K extends Partial<T> = {}> {

    buildCheckBox<NewKey extends BooleanKeysOf<T>>(): FormBuilder<T,AddProp<T,K,NewKey>> {
        return this as any;
    }

    buildBlock<NewKey extends CompoundKeysOf<T>>(key: NewKey): FormBuilder<T,NewKey>> {
        return this as any;
    }

    buildInput<NewKey extends StringOrNumberKeysOf<T>>(): FormBuilder<T,NewKey>> {
        return this as any;
    }

    buildArray<NewKey extends ArrayKeysOf<T>>(): FormBuilder<T,NewKey>> {
        return this as any;
    }

    finishForm(): K extends T ? FormForModel<T> : MissingProps<T,K> { // tells us which props are missing!
        // use childforms to build a complete form
        return 'hello' as any;
    }

    // Get a FormBuilder that accumulates props to build one of the object properties of the parent form
    getChildBuilder<NewKey extends CompoundKeysOf<T>>(): FormBuilder<T[NewKey]> {
        return new FormBuilder();
    }
}

这使用了一些辅助类型:

/**
 * Utility types
 */

// Get from Type T all of the keys that have values of type SomeType
type KeysOfType<T,SomeType> = { [K in keyof T]: T[K] extends SomeType ? K : never }[keyof T]

// Get all keys that are boolean,or string | number,or arrays,or other objects
type BooleanKeysOf<T> = KeysOfType<T,boolean>;
type StringOrNumberKeysOf<T> = KeysOfType<T,string | number>;
type ArrayKeysOf<T> = KeysOfType<T,any[]>;
type CompoundKeysOf<T> = Exclude<KeysOfType<T,object>,ArrayKeysOf<T>>; // get all props that have object types,except arrays

// a type representing the form we're building
type FormForModel<T> = { [K in keyof T]: {} } };

// Add to K another prop that's a part of T
type AddProp<T,K extends Partial<T>,NewKey extends keyof T> = K & { [S in NewKey]: T[S] };

// Which props are missing from K to fill out T?
type MissingProps<T,K extends Partial<T>> = Omit<T,keyof K>;

使用这种方法,可以很容易地将每个函数的类型参数限制为之前没有被调用过的键,直到调用签名变成 NewKey extends never 并且无法进行调用

但是,当函数没有合法值可供调用时,我想从类型签名中完全删除它。我想像这样:

    buildCheckBox<NewKey extends Exclude<BooleanKeysOf<T>,keyof K>>(): MaybeExcludeCheckBox<T,NewKey> {
        return this as any;
    }

type MaybeExcludeCheckBox<T,NewKey extends keyof T> = Exclude<keyof T,NewKey> extends never? Omit<FormBuilder<T,NewKey>>,'buildCheckBox'> : FormBuilder<T,NewKey>>

它的作用是检查是否有任何剩余的布尔属性,如果有则返回 FormBuilder 类型,如果没有,则省略 'buildCheckBox' 属性。但是,有时我想打开或关闭多个功能。每次调用函数时,是否有更简洁的方法添加/删除多个属性

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...