TypeScript reference
These are some of the TypeScript types and interfaces you'll see throughout the documentation. Even if you are not using TypeScript (you really should! 😊), you can use the information below to understand the required shape of the props and function parameters. To see the full type definitions for the react-querybuilder
library, click here.
The minimum TypeScript version for this library is 4.1, but if you use TypeScript 4.5 or greater then the type RuleGroupTypeIC
(the type used for the query
prop when independentCombinators
is true
) will be more accurate and helpful. See the note in the Rules and groups section below.
Fields​
interface Field {
id?: string; // The field identifier (if not provided, then `name` will be used)
name: string; // REQUIRED - the field name
label: string; // REQUIRED - the field label
operators?: NameLabelPair[] | OptionGroup[]; // Array of operators (if not provided, then `getOperators()` will be used)
valueEditorType?: ValueEditorType; // Value editor type for this field (if not provided, then `getValueEditorType()` will be used)
inputType?: string | null; // Input type for text box inputs, e.g. 'text', 'number', or 'date' (if not provided, then `getInputType()` will be used)
values?: NameLabelPair[]; // Array of values, applicable when valueEditorType is 'select' or 'radio' (if not provided, then `getValues()` will be used)
defaultOperator?: string; // Default operator for this field (if not provided, then `getDefaultOperator()` will be used)
defaultValue?: any; // Default value for this field (if not provided, then `getDefaultValue()` will be used)
placeholder?: string; // Value to be displayed in the placeholder of the text field
validator?: RuleValidator; // Called when a rule specifies this field
valueSources?: ValueSources | ((operator: string) => ValueSources); // List of allowed value sources (must contain "value", "field", or both)
comparator?: string | ((f: Field, operator: string) => boolean); // Determines which (other) fields to include in the list when valueSource is "field"
}
Click here for documentation on the available options for valueEditorType
.
Rules and groups​
type RuleType = {
path?: number[];
id?: string;
disabled?: boolean;
field: string;
operator: string;
value: any;
valueSource?: ValueSource;
};
type RuleGroupType = {
path?: number[];
id?: string;
disabled?: boolean;
combinator: string;
rules: (RuleType | RuleGroupType)[];
not?: boolean;
};
type RuleGroupTypeIC = {
path?: number[];
id?: string;
disabled?: boolean;
rules: (RuleType | RuleGroupTypeIC | string)[]; // see note below
not?: boolean;
};
type RuleGroupTypeAny = RuleGroupType | RuleGroupTypeIC;
type RuleOrGroupArray = RuleGroupType['rules'] | RuleGroupTypeIC['rules'];
RuleGroupTypeIC
is greatly simplified here for brevity. In reality, the following conditions will be enforced by TypeScript:
- All even indexes in the
rules
array must be of typeRuleType
orRuleGroupTypeIC
- All odd indexes in the
rules
array must be of typestring
- The first and last elements of the
rules
array must be of typeRuleType
orRuleGroupTypeIC
(therefore the array length, unless it is zero, must be an odd number)
That is, unless you're using a TypeScript version lower than 4.5, in which case what you see above is the actual type definition. I.e., the
rules
array can be of any length, with elements ofRuleType
,RuleGroupTypeIC
, orstring
in any order, and TypeScript will not complain. However, invalid query objects can lead to unexpected behavior from the<QueryBuilder />
component, so TypeScript 4.5 or greater is strongly recommended if theindependentCombinators
option will be used. In any case, make sure query objects meet the conditions listed above.
For example, the following would be invalid because the first element in the rules
array (the 0
th index, which should be RuleType | RuleGroupTypeIC
) is a string
, and the second element (the 1
st index, which should be a string
) is a RuleType
. Also, the length (2) is an even number.
const ruleGroupInvalid: RuleGroupTypeIC = {
rules: ['and', { field: 'firstName', operator: '=', value: 'Steve' }],
};
Either removing the first element or inserting another rule before it will resolve the issue:
const ruleGroupValid1: RuleGroupTypeIC = {
rules: [{ field: 'firstName', operator: '=', value: 'Steve' }],
};
// OR
const ruleGroupValid2: RuleGroupTypeIC = {
rules: [
{ field: 'lastName', operator: '=', value: 'Vai' },
'and',
{ field: 'firstName', operator: '=', value: 'Steve' },
],
};
Export​
type ExportFormat =
| 'json'
| 'sql'
| 'json_without_ids'
| 'parameterized'
| 'parameterized_named'
| 'mongodb'
| 'cel';
type ValueProcessor = (field: string, operator: string, value: any) => string;
interface FormatQueryOptions {
format?: ExportFormat;
valueProcessor?: ValueProcessor;
quoteFieldNamesWith?: string;
validator?: QueryValidator;
fields?: { name: string; validator?: RuleValidator; [k: string]: any }[];
fallbackExpression?: string;
paramPrefix?: string;
parseNumbers?: boolean;
placeholderFieldName?: string;
placeholderOperatorName?: string;
}
interface ParameterizedSQL {
sql: string;
params: any[];
}
interface ParameterizedNamedSQL {
sql: string;
params: { [p: string]: any };
}
Import​
interface ParseSQLOptions {
independentCombinators?: boolean;
paramPrefix?: string;
params?: any[] | { [p: string]: any };
listsAsArrays?: boolean;
fields?: Field[] | OptionGroup<Field>[] | Record<string, Field>;
getValueSources?: (field: string, operator: string) => ValueSources;
}
Validation​
interface ValidationResult {
valid: boolean;
reasons?: any[];
}
interface ValidationMap {
[id: string]: boolean | ValidationResult;
}
type QueryValidator = (query: RuleGroupTypeAny) => boolean | ValidationMap;
type RuleValidator = (rule: RuleType) => boolean | ValidationResult;
Miscellaneous​
interface NameLabelPair {
name: string;
label: string;
[x: string]: any;
}
interface OptionGroup {
label: string;
options: NameLabelPair[];
}
type ValueEditorType =
| 'text'
| 'select'
| 'checkbox'
| 'radio'
| 'textarea'
| 'multiselect'
| 'date'
| 'datetime-local'
| 'time'
| null;
type ValueSource = 'value' | 'field';
type ValueSources = ['value'] | ['value', 'field'] | ['field', 'value'] | ['field'];
interface Schema {
fields: Field[] | OptionGroup<NameLabelPair>[];
fieldMap: { [k: string]: Field };
classNames: Classnames;
combinators: NameLabelPair[] | OptionGroup<NameLabelPair>[];
controls: Controls;
createRule(): RuleType;
createRuleGroup(): RuleGroupTypeAny;
getOperators(field: string): NameLabelPair[] | OptionGroup<NameLabelPair>[];
getValueEditorType(field: string, operator: string): ValueEditorType;
getInputType(field: string, operator: string): string | null;
getValues(field: string, operator: string): NameLabelPair[] | OptionGroup<NameLabelPair>[];
isRuleGroup(ruleOrGroup: RuleType | RuleGroupTypeAny): ruleOrGroup is RuleGroupTypeAny;
onGroupAdd(group: RuleGroupTypeAny, parentPath: number[]): void;
onGroupRemove(path: number[]): void;
onPropChange(
prop: Exclude<keyof RuleType | keyof RuleGroupType, 'id' | 'path'>,
value: any,
path: number[]
): void;
onRuleAdd(rule: RuleType, parentPath: number[]): void;
onRuleRemove(path: number[]): void;
updateIndependentCombinator(value: string, path: number[]): void;
showCombinatorsBetweenRules: boolean;
showNotToggle: boolean;
showCloneButtons: boolean;
autoSelectField: boolean;
placeholderFieldName: string;
autoSelectOperator: boolean;
placeholderOperatorName: string;
addRuleToNewGroups: boolean;
enableDragAndDrop: boolean;
validationMap: ValidationMap;
independentCombinators: boolean;
disabledPaths: number[][];
}