mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 01:13:23 -04:00
* consider optional properties as optional keys in ObjectType * fix type on security config * fix ObjectTypeOptions
This commit is contained in:
parent
41ff32a8e1
commit
653eb4f4d6
3 changed files with 55 additions and 9 deletions
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
|
||||
import { schema } from '..';
|
||||
import { TypeOf } from './object_type';
|
||||
|
||||
test('returns value by default', () => {
|
||||
const type = schema.object({
|
||||
|
@ -350,3 +351,26 @@ test('unknowns = `ignore` affects only own keys', () => {
|
|||
})
|
||||
).toThrowErrorMatchingInlineSnapshot(`"[foo.baz]: definition for this key is missing"`);
|
||||
});
|
||||
|
||||
test('handles optional properties', () => {
|
||||
const type = schema.object({
|
||||
required: schema.string(),
|
||||
optional: schema.maybe(schema.string()),
|
||||
});
|
||||
|
||||
type SchemaType = TypeOf<typeof type>;
|
||||
|
||||
let foo: SchemaType = {
|
||||
required: 'foo',
|
||||
};
|
||||
foo = {
|
||||
required: 'hello',
|
||||
optional: undefined,
|
||||
};
|
||||
foo = {
|
||||
required: 'hello',
|
||||
optional: 'bar',
|
||||
};
|
||||
|
||||
expect(foo).toBeDefined();
|
||||
});
|
||||
|
|
|
@ -26,9 +26,26 @@ export type Props = Record<string, Type<any>>;
|
|||
|
||||
export type TypeOf<RT extends Type<any>> = RT['type'];
|
||||
|
||||
type OptionalProperties<Base extends Props> = Pick<
|
||||
Base,
|
||||
{
|
||||
[Key in keyof Base]: undefined extends TypeOf<Base[Key]> ? Key : never;
|
||||
}[keyof Base]
|
||||
>;
|
||||
|
||||
type RequiredProperties<Base extends Props> = Pick<
|
||||
Base,
|
||||
{
|
||||
[Key in keyof Base]: undefined extends TypeOf<Base[Key]> ? never : Key;
|
||||
}[keyof Base]
|
||||
>;
|
||||
|
||||
// Because of https://github.com/Microsoft/TypeScript/issues/14041
|
||||
// this might not have perfect _rendering_ output, but it will be typed.
|
||||
export type ObjectResultType<P extends Props> = Readonly<{ [K in keyof P]: TypeOf<P[K]> }>;
|
||||
export type ObjectResultType<P extends Props> = Readonly<
|
||||
{ [K in keyof OptionalProperties<P>]?: TypeOf<P[K]> } &
|
||||
{ [K in keyof RequiredProperties<P>]: TypeOf<P[K]> }
|
||||
>;
|
||||
|
||||
interface UnknownOptions {
|
||||
/**
|
||||
|
@ -40,9 +57,7 @@ interface UnknownOptions {
|
|||
unknowns?: 'allow' | 'ignore' | 'forbid';
|
||||
}
|
||||
|
||||
export type ObjectTypeOptions<P extends Props = any> = TypeOptions<
|
||||
{ [K in keyof P]: TypeOf<P[K]> }
|
||||
> &
|
||||
export type ObjectTypeOptions<P extends Props = any> = TypeOptions<ObjectResultType<P>> &
|
||||
UnknownOptions;
|
||||
|
||||
export class ObjectType<P extends Props = any> extends Type<ObjectResultType<P>> {
|
||||
|
|
|
@ -17,7 +17,14 @@
|
|||
* under the License.
|
||||
*/
|
||||
|
||||
import { ValidationError, Type, schema, ObjectType, isConfigSchema } from '@kbn/config-schema';
|
||||
import {
|
||||
ValidationError,
|
||||
Type,
|
||||
schema,
|
||||
ObjectType,
|
||||
TypeOf,
|
||||
isConfigSchema,
|
||||
} from '@kbn/config-schema';
|
||||
import { Stream } from 'stream';
|
||||
import { RouteValidationError } from './validator_error';
|
||||
|
||||
|
@ -85,7 +92,7 @@ type RouteValidationResultType<T extends RouteValidationSpec<any> | undefined> =
|
|||
T extends RouteValidationFunction<any>
|
||||
? ReturnType<T>['value']
|
||||
: T extends Type<any>
|
||||
? ReturnType<T['validate']>
|
||||
? TypeOf<T>
|
||||
: undefined
|
||||
>;
|
||||
|
||||
|
@ -170,7 +177,7 @@ export class RouteValidator<P = {}, Q = {}, B = {}> {
|
|||
* @internal
|
||||
*/
|
||||
public getParams(data: unknown, namespace?: string): Readonly<P> {
|
||||
return this.validate(this.config.params, this.options.unsafe?.params, data, namespace);
|
||||
return this.validate(this.config.params, this.options.unsafe?.params, data, namespace) as P;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -178,7 +185,7 @@ export class RouteValidator<P = {}, Q = {}, B = {}> {
|
|||
* @internal
|
||||
*/
|
||||
public getQuery(data: unknown, namespace?: string): Readonly<Q> {
|
||||
return this.validate(this.config.query, this.options.unsafe?.query, data, namespace);
|
||||
return this.validate(this.config.query, this.options.unsafe?.query, data, namespace) as Q;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -186,7 +193,7 @@ export class RouteValidator<P = {}, Q = {}, B = {}> {
|
|||
* @internal
|
||||
*/
|
||||
public getBody(data: unknown, namespace?: string): Readonly<B> {
|
||||
return this.validate(this.config.body, this.options.unsafe?.body, data, namespace);
|
||||
return this.validate(this.config.body, this.options.unsafe?.body, data, namespace) as B;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue