createType with single trim (#3859)

* createType with single trim

* Adjust

* Template struct extraction

* Adjust

* Additional

* Additional checks
This commit is contained in:
Jaco
2021-08-10 10:28:43 +02:00
committed by GitHub
parent 2b6e66b906
commit 8404170240
2 changed files with 62 additions and 57 deletions
+1 -1
View File
@@ -71,7 +71,7 @@ const tt5 = registry.createType('()');
// nested tuples
const tt6 = registry.createType('(u8, (u16, (u32, u64, u32)), (u64, u64))');
// more nested tuples
const tt7 = registry.createType('(((u8, u8), (u8, u8)), u16)');
const tt7 = registry.createType('(((u8, u16, u32), (u32, u16, u8)), u128, u256)');
// nested tuples with a wrapper
const tt8 = registry.createType('(u8, Vec<(u16, u32)>, Option<(u128, u128)>)');
// same example as above
+61 -56
View File
@@ -7,20 +7,19 @@ import type { Codec, Constructor } from './codec';
import type { ICompact, IEnum, INumber, IOption, IStruct, ITuple, IU8a, IVec } from './interfaces';
import type { InterfaceTypes } from './registry';
export type DetectCodec<T extends Codec, K extends string> = __Expand<K, T>;
export type DetectCodec<T extends Codec, K extends string> = __Expand<__Unspace<K>, T>;
export type DetectConstructor<T extends Codec, K extends string> = Constructor<__Expand<K, T>>;
export type DetectConstructor<T extends Codec, K extends string> = Constructor<DetectCodec<T, K>>;
// trim leading and trailing spaces
export type Trim<K extends string> =
export type __Unspace<K extends string> =
K extends ` ${infer X} ` | ` ${infer X}` | `${infer X} `
? Trim<X>
: K;
? __Unspace<X>
: K extends `${infer A} ${infer B}`
? __Unspace<`${A}${B}`>
: K;
export type __Wrappers = 'Compact' | 'Option' | 'Vec';
export type __Expand<K extends string, T extends Codec = Codec> = __ExpandImpl<Trim<K>, T>;
export type __ExpandImpl<K extends string, T extends Codec> =
export type __Expand<K extends string, T extends Codec = Codec> =
K extends keyof InterfaceTypes
? InterfaceTypes[K]
: T extends ICompact | IEnum | INumber | IOption | IStruct | ITuple | IU8a | IVec
@@ -32,75 +31,81 @@ export type __Compact<X extends string> = __CompactImpl<__Expand<X>>;
export type __CompactImpl<T extends Codec> =
T extends INumber
? Compact<T>
: never;
: Codec;
// handle option types
export type __Option<X extends string> = __OptionImpl<__Expand<X>>;
export type __OptionImpl<T extends Codec> =
T extends Codec
? Option<T>
: never;
: Codec;
export type __Params<X extends string> = __ParamsImpl<Trim<X>>;
export type __ParamsImpl<X extends string> =
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export type __Struct<_ extends string> = Codec;
export type __TupleParams<X extends string> =
X extends `Vec<${infer A}>,${infer B}`
? [__Vec<A>, ...__Params<B>]
: X extends `Option<${infer A}>,${infer B}`
? [__Option<A>, ...__Params<B>]
: X extends `Vec<${infer A}>`
? [__Vec<A>]
? [__Vec<A>, ...__TupleParams<B>]
: X extends `Vec<${infer A}>`
? [__Vec<A>]
: X extends `Option<${infer A}>,${infer B}`
? [__Option<A>, ...__TupleParams<B>]
: X extends `Option<${infer A}>`
? [__Option<A>]
: X extends `${infer A},${infer B}`
? __ParamsTuple<A, B>
: [__ParamsExpand<X>];
export type __ParamsTuple<A extends string, B extends string> = __ParamsTupleImpl<Trim<A>, Trim<B>>;
export type __ParamsTupleImpl<A extends string, B extends string> =
B extends `(${infer C}),${infer D}`
? [__ParamsExpand<A>, __Tuple<C>, ...__Params<D>]
// eslint-disable-next-line @typescript-eslint/no-unused-vars
: B extends `[${infer C}]` | `(${infer C})`
? [__ParamsExpand<A>, __Expand<B>]
: [__ParamsExpand<A>, ...__Params<B>];
export type __ParamsExpand<X extends string> = __ParamsExpandImpl<Trim<X>>;
export type __ParamsExpandImpl<X extends string> =
// flatten nested tuples
X extends `(${infer A})` | `(${infer A}` | `${infer A})`
? __ParamsExpand<A>
: __Expand<X>;
: X extends `Compact<${infer A}>,${infer B}`
? [__Compact<A>, ...__TupleParams<B>]
: X extends `Compact<${infer A}>`
? [__Compact<A>]
: X extends `[${infer A}],${infer B}`
? [__VecFixed<A>, ...__TupleParams<B>]
: X extends `[${infer A}]`
? [__VecFixed<A>]
: X extends `{${infer A}},${infer B}`
? [__Struct<A>, ...__TupleParams<B>]
: X extends `{${infer A}}`
? [__Struct<A>]
// FIXME This also matches ((x, y), ... as (x, y
: X extends `(${infer A}),${infer B}`
? [__Tuple<A>, ...__TupleParams<B>]
: X extends `(${infer A})`
? [__Tuple<A>]
: X extends `${infer A},${infer B}`
? [__Expand<A>, ...__TupleParams<B>]
: [__Expand<X>];
export type __Tuple<X extends string> = __TupleImpl<Trim<X>>;
export type __TupleImpl<X extends string> =
// eslint-disable-next-line @typescript-eslint/no-unused-vars
X extends `${infer A},${infer B}`
? ITuple<__Params<X>>
: __Expand<X>;
export type __Tuple<X extends string> = __TupleWrap<__TupleParams<X>>;
export type __TupleWrap<X extends Codec[]> =
X[1] extends Codec
? ITuple<X>
: X[0];
// vec support with short-circuit for u8
export type __Vec<X extends string> = __VecImpl<Trim<X>>;
export type __VecImpl<X extends string> =
export type __Vec<X extends string> =
X extends 'u8'
? Bytes
: Vec<__Expand<X>>;
// fixed vec support
export type __VecFixed<X extends string, L extends string> = __VecFixedImpl<Trim<X>, L>;
export type __VecFixedImpl<X extends string, L extends string> =
L extends string
? X extends 'u8'
export type __VecFixed<X extends string> =
// eslint-disable-next-line @typescript-eslint/no-unused-vars
X extends `${infer T};${infer _}`
? T extends 'u8'
? Raw
: VecFixed<__Expand<X>>
: never;
: VecFixed<__Expand<T>>
: Codec;
export type __Unwrap<K extends string, T extends Codec> =
K extends `Compact<${infer X}>`
? __Compact<X>
K extends `Vec<${infer X}>`
? __Vec<X>
: K extends `Option<${infer X}>`
? __Option<X>
: K extends `Vec<${infer X}>`
? __Vec<X>
: K extends `[${infer X};${infer L}]`
? __VecFixed<X, L>
: K extends `Compact<${infer X}>`
? __Compact<X>
: K extends `[${infer X}]`
? __VecFixed<X>
: K extends `(${infer X})`
? __Tuple<X>
: T;
: K extends `{${infer X}}`
? __Struct<X>
: T;