createType TS tuple definitions (#3854)

This commit is contained in:
Jaco
2021-08-07 13:12:02 +02:00
committed by GitHub
parent a133fec533
commit e1828af4c4
2 changed files with 71 additions and 25 deletions
+16 -2
View File
@@ -41,8 +41,14 @@ assert(bb.toHuman(), 'All ok');
const ee = registry.createType('Vec<Option<Compact<ReferendumIndex>>>');
// Option<Bytes>
const vb = registry.createType('Option< Vec< u8 > >');
// nested vecs
const vv = registry.createType('Vec< Vec< Vec< Vec<u8>> > >');
// vec with tuple
const vt = registry.createType('Vec<(u8, u16)>');
// nested stuff from all-over
const vn = registry.createType('Vec<(u32, (u32, u64), Vec<u8>, Vec<(u32, u64)>, [u8;32], [u128;32])>');
assert(ee[0].unwrap().unwrap().divn(123) && vb.unwrap().bitLength(), 'All ok');
assert(ee[0].unwrap().unwrap().divn(123) && vb.unwrap().bitLength() && vv.toHuman() && vn.toHuman() && vt.toHuman(), 'All ok');
// Should end up as Raw
const gg = registry.createType('[ u8 ;678]');
@@ -62,5 +68,13 @@ const tt2 = registry.createType('( u32 )');
const tt4 = registry.createType('(u8,u16,u32,u64,u128,u256,Break,u256,u128,u64,u32,u16,u8)');
// empty
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)');
// nested tuples with a wrapper
const tt8 = registry.createType('(u8, Vec<(u16, u32)>, Option<(u128, u128)>)');
// same example as above
const tt9 = registry.createType('(u32, (u32, u64), Vec<u8>, Vec<(u32, u64)>, [u8;32], [u128;32])');
assert(tt1[2].bitLength() && tt2.bitLength() && tt4[3].bitLength() && tt5.isEmpty, 'All ok');
assert(tt1[2].bitLength() && tt2.bitLength() && tt4[3].bitLength() && tt5.isEmpty && tt6[1].toHuman() && tt7.toHuman() && tt8.toHuman() && tt9.toHuman(), 'All ok');
+55 -23
View File
@@ -13,15 +13,14 @@ export type DetectConstructor<T extends Codec, K extends string> = Constructor<_
// trim leading and trailing spaces
export type Trim<K extends string> =
K extends ` ${infer X}`
K extends ` ${infer X} ` | ` ${infer X}` | `${infer X} `
? Trim<X>
: K extends `${infer X} `
? Trim<X>
: K;
: K;
export type __Expand<K extends string, T extends Codec = Codec> = __Internal<Trim<K>, T>;
export type __Wrappers = 'Compact' | 'Option' | 'Vec';
export type __Internal<K extends string, T extends Codec> =
export type __Expand<K extends string, T extends Codec = Codec> = __ExpandImpl<Trim<K>, T>;
export type __ExpandImpl<K extends string, T extends Codec> =
K extends keyof InterfaceTypes
? InterfaceTypes[K]
: T extends ICompact | IEnum | INumber | IOption | IStruct | ITuple | IU8a | IVec
@@ -29,46 +28,79 @@ export type __Internal<K extends string, T extends Codec> =
: __Unwrap<K, T>;
// ensure whatever we wrap is always Compact-capable
export type __Compact<T extends Codec> =
export type __Compact<X extends string> = __CompactImpl<__Expand<X>>;
export type __CompactImpl<T extends Codec> =
T extends INumber
? Compact<T>
: never;
export type __Params<X extends string> =
X extends `${infer A},${infer B}`
? [__Expand<A>, ...__Params<B>]
: [__Expand<X>];
// handle option types
export type __Option<X extends string> = __OptionImpl<__Expand<X>>;
export type __OptionImpl<T extends Codec> =
T extends Codec
? Option<T>
: never;
export type __Tuple<X extends string> =
export type __Params<X extends string> = __ParamsImpl<Trim<X>>;
export type __ParamsImpl<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>]
: 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>;
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>;
// vec support with short-circuit for u8
export type __Vec<X extends string> =
Trim<X> extends 'u8'
export type __Vec<X extends string> = __VecImpl<Trim<X>>;
export type __VecImpl<X extends string> =
X extends 'u8'
? Bytes
: Vec<__Expand<X>>;
// fixed vec support
export type __VecFixed<X extends string> =
// eslint-disable-next-line @typescript-eslint/no-unused-vars
X extends `${infer Y};${infer _}`
? Trim<Y> extends 'u8'
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'
? Raw
: VecFixed<__Expand<Y>>
: VecFixed<__Expand<X>>
: never;
export type __Unwrap<K extends string, T extends Codec> =
K extends `Compact<${infer X}>`
? __Compact<__Expand<X>>
? __Compact<X>
: K extends `Option<${infer X}>`
? Option<__Expand<X>>
? __Option<X>
: K extends `Vec<${infer X}>`
? __Vec<X>
: K extends `[${infer X}]`
? __VecFixed<X>
: K extends `[${infer X};${infer L}]`
? __VecFixed<X, L>
: K extends `(${infer X})`
? __Tuple<X>
: T;