* feat: 🎸 add Values<T>

* feat: 🎸 add UnionToIntersection<T> type

* refactor: 💡 use UnionToIntersection<T> in Canvas from @kbn/

* feat: 🎸 add PublicKeys<T> and PublicContract<T> types

* style: 💄 fix ESLint errors
This commit is contained in:
Vadim Dalecky 2020-02-18 20:52:03 +01:00 committed by GitHub
parent 7763a6055a
commit 6436862dc5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 164 additions and 17 deletions

View file

@ -20,8 +20,12 @@ type B = UnwrapPromise<A>; // string
- `Ensure<T, X>` &mdash; Makes sure `T` is of type `X`.
- `ObservableLike<T>` &mdash; Minimal interface for an object resembling an `Observable`.
- `PublicContract<T>` &mdash; Returns an object with public keys only.
- `PublicKeys<T>` &mdash; Returns public keys of an object.
- `RecursiveReadonly<T>` &mdash; Like `Readonly<T>`, but freezes object recursively.
- `ShallowPromise<T>` &mdash; Same as `Promise` type, but it flat maps the wrapped type.
- `UnionToIntersection<T>` &mdash; Converts a union of types into an intersection.
- `UnwrapObservable<T>` &mdash; Returns wrapped type of an observable.
- `UnwrapPromise<T>` &mdash; Returns wrapped type of a promise.
- `UnwrapPromiseOrReturn<T>` &mdash; Returns wrapped type of a promise or the type itself, if it isn't a promise.
- `Values<T>` &mdash; Returns object or array value types.

View file

@ -69,3 +69,31 @@ export type RecursiveReadonly<T> = T extends (...args: any) => any
: T extends object
? Readonly<{ [K in keyof T]: RecursiveReadonly<T[K]> }>
: T;
/**
* Returns types or array or object values.
*/
export type Values<T> = T extends any[] ? T[number] : T extends object ? T[keyof T] : never;
/**
* Utility type for converting a union of types into an intersection.
*
* This is a bit of "black magic" that will interpret a Union type as an Intersection
* type. This is necessary in the case of distinguishing one collection from
* another.
*/
export type UnionToIntersection<U> = (U extends any
? (k: U) => void
: never) extends (k: infer I) => void
? I
: never;
/**
* Returns public keys of an object.
*/
export type PublicKeys<T> = keyof T;
/**
* Returns an object with public keys only.
*/
export type PublicContract<T> = Pick<T, PublicKeys<T>>;

View file

@ -0,0 +1,33 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { expectType } from 'tsd';
import { PublicContract } from '../index';
class Test {
public str: string = '';
// @ts-ignore
private num: number = 0;
}
type CONTRACT = PublicContract<Test>;
expectType<CONTRACT>({
str: 'foo',
});

View file

@ -0,0 +1,31 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { expectType } from 'tsd';
import { PublicKeys } from '../index';
class Test {
public str: string = '';
// @ts-ignore
private num: number = 0;
}
type KEYS = PublicKeys<Test>;
expectType<KEYS>('str');

View file

@ -0,0 +1,28 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { expectType } from 'tsd';
import { UnionToIntersection } from '../index';
type INTERSECTED = UnionToIntersection<{ foo: 'bar' } | { baz: 'qux' }>;
expectType<INTERSECTED>({
foo: 'bar',
baz: 'qux',
});

View file

@ -0,0 +1,38 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { expectType } from 'tsd';
import { Values } from '../index';
// Arrays
type STRING = Values<string[]>;
type ASDF_FOO = Values<Array<'asdf' | 'foo'>>;
expectType<STRING>('adf');
expectType<ASDF_FOO>('asdf');
expectType<ASDF_FOO>('foo');
// Objects
type STRING2 = Values<Record<number, string>>;
type FOO = Values<Record<number, 'foo'>>;
type BAR = Values<{ foo: 'bar' }>;
expectType<STRING2>('adf');
expectType<FOO>('foo');
expectType<BAR>('bar');

View file

@ -5,7 +5,8 @@
*/
import { ExpressionFunctionDefinition } from 'src/plugins/expressions';
import { UnionToIntersection, CanvasFunction } from '../../types';
import { UnionToIntersection } from '@kbn/utility-types';
import { CanvasFunction } from '../../types';
import { help as all } from './dict/all';
import { help as alterColumn } from './dict/alter_column';

View file

@ -10,22 +10,6 @@ import { functions as browserFunctions } from '../canvas_plugin_src/functions/br
import { functions as serverFunctions } from '../canvas_plugin_src/functions/server';
import { clientFunctions } from '../public/functions';
/**
* Utility type for converting a union of types into an intersection.
*
* This is a bit of "black magic" that will interpret a Union type as an Intersection
* type. This is necessary in this case of distiguishing one collection from
* another in `FunctionError` and `FunctionStrings`.
*/
// prettier-ignore
export type UnionToIntersection<U> =
(U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never;
/**
* Utility type: gathers values of a collection as a type for use as a type.
*/
export type ValuesOf<T extends any[]> = T[number];
/**
* A `ExpressionFunctionFactory` is a powerful type used for any function that produces
* an `ExpressionFunction`. If it does not meet the signature for such a function,