我有以下对象(仅用于测试):
{
type: 'custom',
source: (): number[] => { return [1,2,3,4] },
filters: [
{
text: 'Is in one of',
value: 'iiof',
action: (v: MainType, k: number[]) => true
},
{
text: 'Is not in one of',
value: '!iiof',
action: (v: MainType, k: number[]) => true
}
]
}
我正在尝试构建类型,以便任何filter.action
函数的第二个参数将是source
的返回类型。我可以使用any
,但希望尽可能键入此类型。
我当前的类型如下:
export type FilterCustomImpl<T, K> = {
text: string;
value: string;
action: (v: T, s: K[]) => boolean;
};
export type FilterCustomSchemaField<T, K = any> = {
type: 'custom',
display?: string;
source: () => K[];
filters: FilterCustomImpl<T, K>[]
};
export type FilterSchemaField<T> =
FilterEnumSchemaField |
FilterNumericSchemaField |
FilterStringSchemaField |
FilterCustomSchemaField<T>;
export type FilterSchemaFields<T> = { [index: string]: FilterSchemaField<T> };
export type FilterSchema<T> = {
defaultKey: string;
fields: FilterSchemaFields<T>
};
因此,父FilterSchema
可以有无限数量的FilterCustomSchemaField
,具有不同的K
类型。
目前,在构建过滤器架构时,我可以通过在字段本身上指定类型来解决它,所以
{
type: 'custom',
source: (): number[] => { return [1,2,3,4] },
filters: [
{
text: 'Is in one of',
value: 'iiof',
action: (v: MainType, k: number[]) => true
},
{
text: 'Is not in one of',
value: '!iiof',
action: (v: MainType, k: number[]) => true
}
]
} as FilterCustomSchemaField<MainType, number>
但这不是一个好方法,因为它显然需要额外的输入,并且每次都必须重写主要的T
类型。
如果我可以从K
函数的返回类型中推断出source
类型,那将是理想的选择,但我不确定是否可行。
答案 0 :(得分:1)
我可能会使用curried辅助函数(这种做法是为了解决缺少partial type parameter inference的问题,有关更多详细信息,请参见this answer),以便您可以手动指定{{1 }}一次,并让编译器推断T
的值。 (我知道您将其称为U
,但是习惯上是K
和K
用于键类型,而P
和T
用于键类型。一般类型...并且由于您不将其限制为类似U
之类的键类型,因此我将更改名称。)
这里是:
string | number | symbol
这是它的用法:
const asFilterCustomSchemaField = <T>() => <U>(
x: FilterCustomSchemaField<T, U>
) => x;
请注意,值如何根据需要设置为const filterCustomSchemaField = asFilterCustomSchemaField<MainType>()({
type: "custom",
source: () => [1, 2, 3, 4],
filters: [
{
text: "Is in one of",
value: "iiof",
action: (v, k) => true // v is inferred as MainType, k as number[]
},
{
text: "Is not in one of",
value: "!iiof",
action: (v, k) => true // v is inferred as MainType, k as number[]
}
]
});
// const filterCustomSchemaField: FilterCustomSchemaField<MainType, number>
类型,其中仅从值中推断出FilterCustomSchemaFiled<MainType, number>
,并指定了number
。如果您使用IntelliSense并将鼠标悬停在MainType
属性中的v
和k
上,您也会看到它们分别被推断为action
和MainType
好的,希望能有所帮助;祝你好运!