-
Notifications
You must be signed in to change notification settings - Fork 28
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Typescript types declaration. #19
Comments
Typescript types declaration in rsuite |
Hi, thanks, good to know that there is declaration: I very like that lib, have simple reasonable api, supports es6, and do not have any dependencies, I checked 20 different similar libs, and I very like to use that one in my project, and I do not using RSuite as I do not using the React there at all, so:
interface A {a: string, b?: number}
// Example of schema with provided type
const typedSchema = new Schema<A>({
a: NumberType(), // Error Type 'INumberType<Partial<A>>' is not assignable to type 'IType<string, Partial<A>>'... Type 'number' is not assignable to type 'string'.
// for autocast of data in addRule we can also add type here
b: NumberType<A>().isRequired('Required').addRule((value, data) => {
let v: string = value; // Error: Type 'number' is not assignable to type 'string'
let d: {x: any} = data; // Error: Property 'x' is missing in type 'A' but required in type '{ x: any; }'.
}),
c: BooleanType(), // Error: Argument of type '{ a: INumberType<any>; b: INumberType<A>; c: IBooleanType<any>; }' is not assignable to parameter of type 'ISchema<Partial<A>>'.
});
typedSchema.check({ c: 12}); //Error: Argument of type '{ c: number; }' is not assignable to parameter of type 'A'
typedSchema.checkForField('x', '12'); //Error: Argument of type '"x"' is not assignable to parameter of type '"a" | "b" | "c"'.
// Example of schema without provided type
// The validation object type will be inferred
const noTypedSchema = new Schema({
a: NumberType(),
b: NumberType().isRequired('Required').addRule((value, data) => {
let v: string = value; // Error: Type 'number' is not assignable to type 'string'
let d: {x: any} = data;
}),
c: BooleanType(),
});
noTypedSchema.check({ c: 12}); //Error: Type 'number' is not assignable to type 'boolean'.
noTypedSchema.checkForField('x', '12'); //Error: Argument of type '"x"' is not assignable to parameter of type '"a" | "b" | "c"'.
// Example of schema with any type provided
const anySchema = new Schema<any>({
a: NumberType(),
b: NumberType().isRequired('Required').addRule((value, data) => {
let v: string = value; // Error: Type 'number' is not assignable to type 'string'
let d: {x: any} = data;
}),
c: BooleanType(),
});
anySchema.check({ c: 12});
anySchema.checkForField('x', '12'); You can plat with that here I created prototype of such declaration which allows such static checks: export type RuleFn<V, D> = (value: V, data: D) =>
FieldSchemaCheckResult | boolean | void | undefined | Promise<boolean> | Promise<FieldSchemaCheckResult> | Promise<void>;
export interface IType<P, T> {
addRule(onValid: RuleFn<P, T>, errorMessage?: string, priority?: boolean): this;
}
export interface IStringType<T = any> extends IType<string, T> {
isRequired(errorMessage?: string, trim?: boolean): this;
isEmail(errorMessage?: string): this;
isURL(errorMessage?: string): this;
isOneOf(items: Array<string>, errorMessage?: string): this;
containsLetter(errorMessage?: string): this;
containsUppercaseLetter(errorMessage?: string): this;
containsLowercaseLetter(errorMessage?: string): this;
containsLetterOnly(errorMessage?: string): this;
containsNumber(errorMessage?: string): this;
pattern(regExp: RegExp, errorMessage?: string): this;
rangeLength(minLength: number, maxLength: number, errorMessage?: string): this;
minLength(minLength: number, errorMessage?: string): this;
maxLength(maxLength: number, errorMessage?: string): this;
}
export interface INumberType<T = any> extends IType<number, T> {
isRequired(errorMessage?: string): this;
isInteger(errorMessage?: string): this;
isOneOf(items: Array<number>, errorMessage?: string): this;
pattern(regExp: RegExp, errorMessage?: string): this;
range(minLength: number, maxLength: number, errorMessage?: string): this;
min(min: number, errorMessage?: string): this;
max(max: number, errorMessage?: string): this;
}
export interface IArrayType<I = any, T = any> extends IType<Array<I>, T> {
isRequired(errorMessage?: string): this;
rangeLength(minLength: number, maxLength: number, errorMessage?: string): this;
minLength(minLength: number, errorMessage?: string): this;
maxLength(maxLength: number, errorMessage?: string): this;
unrepeatable(errorMessage?: string): this;
of(type: IType<I, T>, errorMessage?: string): this;
}
export interface IDateType<T = any> extends IType<Date, T> {
isRequired(errorMessage?: string): this;
range(min: Date, max: Date, errorMessage?: string): this;
min(min: Date, errorMessage?: string): this;
max(max: Date, errorMessage?: string): this;
}
export interface IObjectType<O = any, T = any> extends IType<O, T> {
isRequired(errorMessage?: string): this;
shape(shape: ISchema<O>): this;
}
export interface IBooleanType<T = any> extends IType<boolean, T> {
isRequired(errorMessage?: string): this;
}
type IType<X, T> =
T extends any ? any :
X extends string ? IStringType<T>:
X extends number ? INumberType<T>:
X extends boolean ? IBooleanType<T>:
X extends Date ? IDateType<T>:
X extends Array<infer I> ? IArrayType<I, T>:
X extends any ?
IStringType<T> | INumberType<T> | IBooleanType<T> | IArrayType<any, T> | IDateType<T> | IObjectType<X, T> :
IObjectType<X, T>;
export type ISchema<T> = {
[P in keyof T]: IType<T[P], T>;
}
export type FieldSchemaCheckResult = {
hasError: boolean,
errorMessage: string
}
export type SchemaCheckResult<T> = {
[P in keyof T]: FieldSchemaCheckResult
};
export interface ISchemaModel<T = any> {
schema: ISchema<T>;
check(data: T): SchemaCheckResult<T>;
checkAsync(data: T): Promise<SchemaCheckResult<T>>;
checkForField<K extends keyof T>(fieldName: K, fieldValue: T[K], data?: T): FieldSchemaCheckResult;
checkForFieldAsync<K extends keyof T>(fieldName: K, fieldValue: T[K], data?: T): Promise<FieldSchemaCheckResult>;
getFieldType<K extends keyof T>(fieldName: K): IType<T[K], T>;
getKeys(): Array<PropertyKey>;
}
export interface ISchemaModelFactory {
<T>(schema: ISchema<Partial<T>>): ISchemaModel<T>;
combine<T>(...schemas: Array<ISchemaModel<Partial<T>>>): ISchemaModel<T>;
}
export declare const SchemaModel: ISchemaModelFactory;
export declare function StringType<T = any>(errorMessage?: string): IStringType<T>;
export declare function NumberType<T = any>(errorMessage?: string): INumberType<T>;
export declare function BooleanType<T = any>(errorMessage?: string): IBooleanType<T>;
export declare function ArrayType<I = any, T = any>(errorMessage?: string): IArrayType<I, T>;
export declare function DateType<T = any>(errorMessage?: string): IDateType<T>;
export declare function ObjectType<O = any, T = any>(errorMessage?: string): IObjectType<O, T>;
export declare class Schema<T = any> {
constructor(schema: ISchema<Partial<T>>);
check(data: T): SchemaCheckResult<T>;
checkAsync(data: T): Promise<SchemaCheckResult<T>>;
checkForField<K extends keyof T>(fieldName: K, fieldValue: T[K], data?: T): FieldSchemaCheckResult;
checkForFieldAsync<K extends keyof T>(fieldName: K, fieldValue: T[K], data?: T): Promise<FieldSchemaCheckResult>;
schema: ISchema<T>;
getFieldType<K extends keyof T>(fieldName: K): IType<T[K], T>;
getKeys(): Array<PropertyKey>;
} |
|
As this becomes as an standard, and allows wider adoption, it is worth to add to library the typescript types declaration.
The text was updated successfully, but these errors were encountered: