mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Fix type errors using raw InputValidator (#5704)
- Introduce LegacyInputValidator type Signed-off-by: Sebastian Malton <sebastian@malton.name>
This commit is contained in:
parent
6d484a45e5
commit
eddefb2074
@ -3,6 +3,7 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import type { InputValidator } from "../input_validators";
|
||||||
import { isEmail, isUrl, systemName, unionInputValidators, unionInputValidatorsAsync } from "../input_validators";
|
import { isEmail, isUrl, systemName, unionInputValidators, unionInputValidatorsAsync } from "../input_validators";
|
||||||
|
|
||||||
type TextValidationCase = [string, boolean];
|
type TextValidationCase = [string, boolean];
|
||||||
@ -146,4 +147,12 @@ describe("input validation tests", () => {
|
|||||||
expect(systemName.validate(input)).toBe(output);
|
expect(systemName.validate(input)).toBe(output);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("should allow InputValidator to be used without any type params", () => {
|
||||||
|
const v: InputValidator = {
|
||||||
|
validate: (input: string) => input.length > 10,
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(v.validate("hello")).toBe(false);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -178,7 +178,11 @@ export class Input extends React.Component<InputProps, State> {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isAsyncValidator(validator)) {
|
const result = validator.validate(value, this.props);
|
||||||
|
|
||||||
|
if (typeof result === "boolean" && !result) {
|
||||||
|
errors.push(this.getValidatorError(value, validator));
|
||||||
|
} else if (result instanceof Promise) {
|
||||||
if (!validationId) {
|
if (!validationId) {
|
||||||
this.validationId = validationId = uniqueId("validation_id_");
|
this.validationId = validationId = uniqueId("validation_id_");
|
||||||
}
|
}
|
||||||
@ -189,8 +193,6 @@ export class Input extends React.Component<InputProps, State> {
|
|||||||
return this.getValidatorError(value, validator) || (error instanceof Error ? error.message : String(error));
|
return this.getValidatorError(value, validator) || (error instanceof Error ? error.message : String(error));
|
||||||
}
|
}
|
||||||
})());
|
})());
|
||||||
} else if (!validator.validate(value, this.props)) {
|
|
||||||
errors.push(this.getValidatorError(value, validator));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -18,38 +18,58 @@ export type InputValidation<IsAsync extends boolean> = (value: string, props?: I
|
|||||||
|
|
||||||
export type SyncValidationMessage = React.ReactNode | ((value: string, props?: InputProps) => React.ReactNode);
|
export type SyncValidationMessage = React.ReactNode | ((value: string, props?: InputProps) => React.ReactNode);
|
||||||
|
|
||||||
export type InputValidator<IsAsync extends boolean = boolean> = {
|
/**
|
||||||
|
* @deprecated This type is not as type safe as it is possible to specify an async input validator without specifying a `debounce` time.
|
||||||
|
*
|
||||||
|
* Use {@link asyncInputValidator} or {@link inputValidator} instead to create validators
|
||||||
|
*/
|
||||||
|
export interface LegacyInputValidator {
|
||||||
/**
|
/**
|
||||||
* Filters itself based on the input props
|
* Filters itself based on the input props
|
||||||
*/
|
*/
|
||||||
condition?: (props: InputProps) => any;
|
condition?: (props: InputProps) => any;
|
||||||
} & (
|
validate: InputValidation<boolean>;
|
||||||
IsAsync extends true
|
message?: SyncValidationMessage;
|
||||||
? {
|
debounce?: number;
|
||||||
/**
|
}
|
||||||
* The validation message maybe either specified from the `message` field (higher priority)
|
|
||||||
* or if that is not provided then the message will retrived from the rejected with value
|
|
||||||
*/
|
|
||||||
validate: InputValidation<true>;
|
|
||||||
message?: SyncValidationMessage;
|
|
||||||
debounce: number;
|
|
||||||
}
|
|
||||||
: {
|
|
||||||
validate: InputValidation<false>;
|
|
||||||
message: SyncValidationMessage;
|
|
||||||
debounce?: undefined;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
export function isAsyncValidator(validator: InputValidator<boolean>): validator is InputValidator<true> {
|
export interface AsyncInputValidator {
|
||||||
|
/**
|
||||||
|
* Filters itself based on the input props
|
||||||
|
*/
|
||||||
|
condition?: (props: InputProps) => any;
|
||||||
|
validate: InputValidation<true>;
|
||||||
|
message?: SyncValidationMessage;
|
||||||
|
debounce: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SyncInputValidator {
|
||||||
|
/**
|
||||||
|
* Filters itself based on the input props
|
||||||
|
*/
|
||||||
|
condition?: (props: InputProps) => any;
|
||||||
|
validate: InputValidation<false>;
|
||||||
|
message: SyncValidationMessage;
|
||||||
|
debounce?: undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type InputValidator<IsAsync extends boolean = boolean> = SyncInputValidator | AsyncInputValidator | (IsAsync extends boolean ? LegacyInputValidator : never);
|
||||||
|
|
||||||
|
export function isAsyncValidator(validator: InputValidator): validator is AsyncInputValidator {
|
||||||
return typeof validator.debounce === "number";
|
return typeof validator.debounce === "number";
|
||||||
}
|
}
|
||||||
|
|
||||||
export function asyncInputValidator(validator: InputValidator<true>): InputValidator<true> {
|
/**
|
||||||
|
* A helper function to create an {@link AsyncInputValidator}
|
||||||
|
*/
|
||||||
|
export function asyncInputValidator(validator: AsyncInputValidator): AsyncInputValidator {
|
||||||
return validator;
|
return validator;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function inputValidator(validator: InputValidator<false>): InputValidator<false> {
|
/**
|
||||||
|
* A helper function to create an {@link SyncInputValidator}
|
||||||
|
*/
|
||||||
|
export function inputValidator(validator: SyncInputValidator): SyncInputValidator {
|
||||||
return validator;
|
return validator;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,9 +78,9 @@ export function inputValidator(validator: InputValidator<false>): InputValidator
|
|||||||
* one of the input validators matches the input
|
* one of the input validators matches the input
|
||||||
*/
|
*/
|
||||||
export function unionInputValidators(
|
export function unionInputValidators(
|
||||||
baseValidator: Pick<InputValidator<false>, "condition" | "message">,
|
baseValidator: Pick<SyncInputValidator, "condition" | "message">,
|
||||||
...validators: InputValidator<false>[]
|
...validators: SyncInputValidator[]
|
||||||
): InputValidator<false> {
|
): SyncInputValidator {
|
||||||
return inputValidator({
|
return inputValidator({
|
||||||
...baseValidator,
|
...baseValidator,
|
||||||
validate: (value, props) => validators.some(validator => validator.validate(value, props)),
|
validate: (value, props) => validators.some(validator => validator.validate(value, props)),
|
||||||
@ -72,13 +92,13 @@ export function unionInputValidators(
|
|||||||
* valid if one of the input validators matches the input
|
* valid if one of the input validators matches the input
|
||||||
*/
|
*/
|
||||||
export function unionInputValidatorsAsync(
|
export function unionInputValidatorsAsync(
|
||||||
baseValidator: SetRequired<Pick<InputValidator<boolean>, "condition" | "message">, "message">,
|
baseValidator: SetRequired<Pick<InputValidator, "condition" | "message">, "message">,
|
||||||
...validators: InputValidator<boolean>[]
|
...validators: InputValidator[]
|
||||||
): InputValidator<true> {
|
): AsyncInputValidator {
|
||||||
const longestDebounce = Math.max(
|
const longestDebounce = Math.max(
|
||||||
...validators
|
...validators
|
||||||
.filter(isAsyncValidator)
|
.filter(isAsyncValidator)
|
||||||
.map(validator => validator.debounce),
|
.map(validator => validator.debounce ?? 0),
|
||||||
0,
|
0,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user