diff --git a/CHANGELOG.md b/CHANGELOG.md index a74798867b..245ebf4326 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,11 @@ ## master +- **Important** The `ClassOf` alias for `createClass` has been removed, us `createClass` (with new generics) directly + Changes: +- `createType('...': K)` now returns `Codec` when `K` is not in the InterfaceRegistry, with `T` override - Handle `BitSequence` in `PortableRegistry` - Move all static test support files into `@polkadot/types-support` - Align static Metadata with latest Substrate, Polkadot & Kusama diff --git a/packages/api-derive/src/democracy/dispatchQueue.ts b/packages/api-derive/src/democracy/dispatchQueue.ts index a3e29ab316..30fa29a978 100644 --- a/packages/api-derive/src/democracy/dispatchQueue.ts +++ b/packages/api-derive/src/democracy/dispatchQueue.ts @@ -86,7 +86,7 @@ function queryScheduler (api: ApiInterfaceRx): Observable { const id = scheduled.maybeId.unwrap().toHex(); if (id.startsWith(DEMOCRACY_ID)) { - const [, index] = api.registry.createType('(u64, ReferendumIndex)' as any, id) as ITuple<[u64, ReferendumIndex]>; + const [, index] = api.registry.createType>('(u64, ReferendumIndex)', id); const imageHash = scheduled.call.args[0] as Hash; result.push({ at, imageHash, index }); diff --git a/packages/api-derive/src/index.spec.ts b/packages/api-derive/src/index.spec.ts index 5d03f82fc3..c6463768fa 100644 --- a/packages/api-derive/src/index.spec.ts +++ b/packages/api-derive/src/index.spec.ts @@ -14,10 +14,7 @@ import { TypeRegistry } from '@polkadot/types/create'; import { ExactDerive } from '.'; const testFunction = (api: ApiRx): any => { - return < - Section extends keyof ExactDerive, - Method extends keyof (typeof api.derive[Section]) - >(section: Section, method: Method, inputs: any[]): void => { + return (section: S, method: M, inputs: any[]): void => { describe(`derive.${section}.${method}`, (): void => { it('should be a function', (): void => { expect(typeof api.derive[section][method]).toBe('function'); @@ -96,7 +93,7 @@ describe('derive', (): void => { testFunction(api)('balances', 'fees', ['a', 'b']); // new - testFunction(api)('custom' as any, 'test', [1, 2, 3]); + testFunction(api)('custom', 'test', [1, 2, 3]); // existing testFunction(api)('chain', 'bestNumber', []); diff --git a/packages/typegen/src/util/derived.ts b/packages/typegen/src/util/derived.ts index 375e2c32af..48ae67b023 100644 --- a/packages/typegen/src/util/derived.ts +++ b/packages/typegen/src/util/derived.ts @@ -6,7 +6,7 @@ import type { Constructor, Registry } from '@polkadot/types/types'; import { Compact, Enum, Option, Struct, Tuple, UInt, Vec } from '@polkadot/types/codec'; import { AbstractInt } from '@polkadot/types/codec/AbstractInt'; -import { ClassOfUnsafe, getTypeDef } from '@polkadot/types/create'; +import { getTypeDef } from '@polkadot/types/create'; import { TypeDefInfo } from '@polkadot/types/create/types'; import { GenericAccountId, GenericLookupSource, GenericVote } from '@polkadot/types/generic'; import { AllConvictions } from '@polkadot/types/interfaces/democracy/definitions'; @@ -30,7 +30,7 @@ export function getDerivedTypes (registry: Registry, definitions: Record)[primitiveName] || - ClassOfUnsafe(registry, type) + registry.createClass(type) ); const def = getTypeDef(type); @@ -87,7 +87,7 @@ export function getSimilarTypes (registry: Registry, definitions: Record('Something'); + + assert(dd.divn(123), 'All ok'); +} + +registryCheck(new TypeRegistry()); diff --git a/packages/types/src/codec/BTreeMap.spec.ts b/packages/types/src/codec/BTreeMap.spec.ts index 92e8dcec6d..1f4563f22f 100644 --- a/packages/types/src/codec/BTreeMap.spec.ts +++ b/packages/types/src/codec/BTreeMap.spec.ts @@ -69,7 +69,7 @@ describe('BTreeMap', (): void => { it('decodes within more complicated types', (): void => { const s = new Struct(registry, { placeholder: U32, - value: 'BTreeMap' as 'u32' + value: 'BTreeMap' }); s.set('value', new (BTreeMap.with(Text, U32))(registry, mockU32TextMap)); diff --git a/packages/types/src/codec/BTreeMap.ts b/packages/types/src/codec/BTreeMap.ts index 4aab90f219..0536231041 100644 --- a/packages/types/src/codec/BTreeMap.ts +++ b/packages/types/src/codec/BTreeMap.ts @@ -1,12 +1,12 @@ // Copyright 2017-2021 @polkadot/types authors & contributors // SPDX-License-Identifier: Apache-2.0 -import type { Codec, Constructor, InterfaceTypes, Registry } from '../types'; +import type { Codec, Constructor, Registry } from '../types'; import { CodecMap } from './Map'; export class BTreeMap extends CodecMap { - public static with (keyType: Constructor | keyof InterfaceTypes, valType: Constructor | keyof InterfaceTypes): Constructor> { + public static with (keyType: Constructor | string, valType: Constructor | string): Constructor> { return class extends BTreeMap { constructor (registry: Registry, value?: Uint8Array | string | Map) { super(registry, keyType, valType, value, 'BTreeMap'); diff --git a/packages/types/src/codec/BTreeSet.ts b/packages/types/src/codec/BTreeSet.ts index 027eebe78d..914653bd49 100644 --- a/packages/types/src/codec/BTreeSet.ts +++ b/packages/types/src/codec/BTreeSet.ts @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import type { CodecHash, Hash } from '../interfaces/runtime'; -import type { AnyJson, Codec, Constructor, InterfaceTypes, Registry } from '../types'; +import type { AnyJson, Codec, Constructor, Registry } from '../types'; import { compactFromU8a, compactToU8a, isHex, isU8a, logger, stringify, u8aConcat, u8aToHex, u8aToU8a } from '@polkadot/util'; @@ -60,7 +60,7 @@ function decodeSetFromSet (registry: Registry, ValClass * @param jsonSet * @internal */ -function decodeSet (registry: Registry, valType: Constructor | keyof InterfaceTypes, value?: Uint8Array | string | string[] | Set): Set { +function decodeSet (registry: Registry, valType: Constructor | string, value?: Uint8Array | string | string[] | Set): Set { if (!value) { return new Set(); } @@ -83,14 +83,14 @@ export class BTreeSet extends Set implements Codec { readonly #ValClass: Constructor; - constructor (registry: Registry, valType: Constructor | keyof InterfaceTypes, rawValue?: Uint8Array | string | string[] | Set) { + constructor (registry: Registry, valType: Constructor | string, rawValue?: Uint8Array | string | string[] | Set) { super(sortSet(decodeSet(registry, valType, rawValue))); this.registry = registry; this.#ValClass = typeToConstructor(registry, valType); } - public static with (valType: Constructor | keyof InterfaceTypes): Constructor> { + public static with (valType: Constructor | string): Constructor> { return class extends BTreeSet { constructor (registry: Registry, value?: Uint8Array | string | Set) { super(registry, valType, value); diff --git a/packages/types/src/codec/Compact.ts b/packages/types/src/codec/Compact.ts index 4f04145758..fc1a22c7a7 100644 --- a/packages/types/src/codec/Compact.ts +++ b/packages/types/src/codec/Compact.ts @@ -3,7 +3,7 @@ import type { BN } from '@polkadot/util'; import type { CodecHash, Hash } from '../interfaces'; -import type { AnyJson, AnyNumber, Constructor, ICompact, InterfaceTypes, Registry } from '../types'; +import type { AnyJson, AnyNumber, Constructor, ICompact, Registry } from '../types'; import type { CompactEncodable } from './types'; import { compactFromU8a, compactToU8a, isBigInt, isBn, isNumber, isString } from '@polkadot/util'; @@ -27,13 +27,13 @@ export class Compact implements ICompact { readonly #raw: T; - constructor (registry: Registry, Type: Constructor | keyof InterfaceTypes, value: Compact | AnyNumber = 0) { + constructor (registry: Registry, Type: Constructor | string, value: Compact | AnyNumber = 0) { this.registry = registry; this.#Type = typeToConstructor(registry, Type); this.#raw = Compact.decodeCompact(registry, this.#Type, value) as T; } - public static with (Type: Constructor | keyof InterfaceTypes): Constructor> { + public static with (Type: Constructor | string): Constructor> { return class extends Compact { constructor (registry: Registry, value?: Compact | AnyNumber) { super(registry, Type, value); diff --git a/packages/types/src/codec/Enum.ts b/packages/types/src/codec/Enum.ts index b7194ec989..c3cfaf8dde 100644 --- a/packages/types/src/codec/Enum.ts +++ b/packages/types/src/codec/Enum.ts @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import type { CodecHash, Hash } from '../interfaces'; -import type { AnyJson, Codec, Constructor, InterfaceTypes, Registry } from '../types'; +import type { AnyJson, Codec, Constructor, Registry } from '../types'; import { assert, hexToU8a, isHex, isNumber, isObject, isString, isU8a, isUndefined, stringCamelCase, stringify, stringUpperFirst, u8aConcat, u8aToHex } from '@polkadot/util'; @@ -27,7 +27,7 @@ interface Decoded { value: Codec; } -function isRustEnum (def: Record | Record): def is Record { +function isRustEnum (def: Record | Record): def is Record { const defValues = Object.values(def); if (defValues.some((v) => isNumber(v))) { @@ -39,7 +39,7 @@ function isRustEnum (def: Record | R return true; } -function extractDef (registry: Registry, _def: Record | Record | string[]): { def: TypesDef; isBasic: boolean; isIndexed: boolean } { +function extractDef (registry: Registry, _def: Record | Record | string[]): { def: TypesDef; isBasic: boolean; isIndexed: boolean } { if (Array.isArray(_def)) { return { def: _def.reduce((def: TypesDef, key, index): TypesDef => { @@ -180,7 +180,7 @@ export class Enum implements Codec { readonly #raw: Codec; - constructor (registry: Registry, def: Record | Record | string[], value?: unknown, index?: number) { + constructor (registry: Registry, def: Record | Record | string[], value?: unknown, index?: number) { const defInfo = extractDef(registry, def); const decoded = decodeEnum(registry, defInfo.def, value, index); @@ -193,7 +193,7 @@ export class Enum implements Codec { this.#raw = decoded.value; } - public static with (Types: Record | Record | string[]): EnumConstructor { + public static with (Types: Record | Record | string[]): EnumConstructor { return class extends Enum { constructor (registry: Registry, value?: unknown, index?: number) { super(registry, Types, value, index); diff --git a/packages/types/src/codec/HashMap.ts b/packages/types/src/codec/HashMap.ts index 9002d62037..7dec233fa8 100644 --- a/packages/types/src/codec/HashMap.ts +++ b/packages/types/src/codec/HashMap.ts @@ -1,12 +1,12 @@ // Copyright 2017-2021 @polkadot/types authors & contributors // SPDX-License-Identifier: Apache-2.0 -import type { Codec, Constructor, InterfaceTypes, Registry } from '../types'; +import type { Codec, Constructor, Registry } from '../types'; import { CodecMap } from './Map'; export class HashMap extends CodecMap { - public static with (keyType: Constructor | keyof InterfaceTypes, valType: Constructor | keyof InterfaceTypes): Constructor> { + public static with (keyType: Constructor | string, valType: Constructor | string): Constructor> { return class extends HashMap { constructor (registry: Registry, value?: Uint8Array | string | Map) { super(registry, keyType, valType, value); diff --git a/packages/types/src/codec/Linkage.spec.ts b/packages/types/src/codec/Linkage.spec.ts index ad7aee10dc..3bf66ca70e 100644 --- a/packages/types/src/codec/Linkage.spec.ts +++ b/packages/types/src/codec/Linkage.spec.ts @@ -25,7 +25,7 @@ describe('Linkage', (): void => { ).toEqual(LINKA); expect( registry.createType( - 'Linkage' as 'u32', + 'Linkage', '0x0001da30b68f54f686f586ddb29de12b682dd8bd1404566fb8a8db5dec20aa5b6b36' ).toHuman() ).toEqual(LINKA); @@ -33,7 +33,7 @@ describe('Linkage', (): void => { // actual check expect( registry.createType( - '(ValidatorPrefsWithCommission, Linkage)' as 'u32', + '(ValidatorPrefsWithCommission, Linkage)', '0x0284d7170001da30b68f54f686f586ddb29de12b682dd8bd1404566fb8a8db5dec20aa5b6b36' ).toHuman() ).toEqual([PREFS, LINKA]); diff --git a/packages/types/src/codec/Linkage.ts b/packages/types/src/codec/Linkage.ts index b93801ce29..8724cfc77c 100644 --- a/packages/types/src/codec/Linkage.ts +++ b/packages/types/src/codec/Linkage.ts @@ -1,7 +1,7 @@ // Copyright 2017-2021 @polkadot/types authors & contributors // SPDX-License-Identifier: Apache-2.0 -import type { Codec, Constructor, InterfaceTypes, Registry } from '../types'; +import type { Codec, Constructor, Registry } from '../types'; import { Option } from './Option'; import { Struct } from './Struct'; @@ -17,7 +17,7 @@ const EMPTY = new Uint8Array(); * @description The wrapper for the result from a LinkedMap */ export class Linkage extends Struct { - constructor (registry: Registry, Type: Constructor | keyof InterfaceTypes, value?: unknown) { + constructor (registry: Registry, Type: Constructor | string, value?: unknown) { super(registry, { previous: Option.with(Type), // eslint-disable-next-line sort-keys @@ -25,7 +25,7 @@ export class Linkage extends Struct { }, value as string); } - public static withKey (Type: Constructor | keyof InterfaceTypes): Constructor> { + public static withKey (Type: Constructor | string): Constructor> { return class extends Linkage { constructor (registry: Registry, value?: unknown) { super(registry, Type, value); diff --git a/packages/types/src/codec/Map.ts b/packages/types/src/codec/Map.ts index 56040c5f35..a1c4424b04 100644 --- a/packages/types/src/codec/Map.ts +++ b/packages/types/src/codec/Map.ts @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import type { CodecHash, Hash } from '../interfaces/runtime'; -import type { AnyJson, Codec, Constructor, InterfaceTypes, Registry } from '../types'; +import type { AnyJson, Codec, Constructor, Registry } from '../types'; import { compactFromU8a, compactToU8a, isHex, isObject, isU8a, logger, stringify, u8aConcat, u8aToHex, u8aToU8a } from '@polkadot/util'; @@ -75,7 +75,7 @@ function decodeMapFromMap (reg * @param jsonMap * @internal */ -function decodeMap (registry: Registry, keyType: Constructor | keyof InterfaceTypes, valType: Constructor | keyof InterfaceTypes, value?: Uint8Array | string | Map): Map { +function decodeMap (registry: Registry, keyType: Constructor | string, valType: Constructor | string, value?: Uint8Array | string | Map): Map { const KeyClass = typeToConstructor(registry, keyType); const ValClass = typeToConstructor(registry, valType); @@ -103,7 +103,7 @@ export class CodecMap extends readonly #type: string; - constructor (registry: Registry, keyType: Constructor | keyof InterfaceTypes, valType: Constructor | keyof InterfaceTypes, rawValue: Uint8Array | string | Map | undefined, type: 'BTreeMap' | 'HashMap' = 'HashMap') { + constructor (registry: Registry, keyType: Constructor | string, valType: Constructor | string, rawValue: Uint8Array | string | Map | undefined, type: 'BTreeMap' | 'HashMap' = 'HashMap') { const decoded = decodeMap(registry, keyType, valType, rawValue); super(type === 'BTreeMap' ? sortMap(decoded) : decoded); diff --git a/packages/types/src/codec/Option.ts b/packages/types/src/codec/Option.ts index 24333f70e8..1faf45dcd0 100644 --- a/packages/types/src/codec/Option.ts +++ b/packages/types/src/codec/Option.ts @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import type { CodecHash, Hash } from '../interfaces'; -import type { AnyJson, Codec, Constructor, InterfaceTypes, Registry } from '../types'; +import type { AnyJson, Codec, Constructor, Registry } from '../types'; import { assert, isNull, isU8a, isUndefined, u8aToHex } from '@polkadot/util'; @@ -17,7 +17,7 @@ function decodeOptionU8a (registry: Registry, Type: Constructor, value: Uint8Arr } /** @internal */ -function decodeOption (registry: Registry, typeName: Constructor | keyof InterfaceTypes, value?: unknown): Codec { +function decodeOption (registry: Registry, typeName: Constructor | string, value?: unknown): Codec { if (isNull(value) || isUndefined(value) || value instanceof Null) { return new Null(registry); } @@ -56,13 +56,13 @@ export class Option implements Codec { readonly #raw: T; - constructor (registry: Registry, typeName: Constructor | keyof InterfaceTypes, value?: unknown) { + constructor (registry: Registry, typeName: Constructor | string, value?: unknown) { this.registry = registry; this.#Type = typeToConstructor(registry, typeName); this.#raw = decodeOption(registry, typeName, value) as T; } - public static with (Type: Constructor | keyof InterfaceTypes): Constructor> { + public static with (Type: Constructor | string): Constructor> { return class extends Option { constructor (registry: Registry, value?: unknown) { super(registry, Type, value); diff --git a/packages/types/src/codec/Result.ts b/packages/types/src/codec/Result.ts index d35741b2cf..2ba5ff0ace 100644 --- a/packages/types/src/codec/Result.ts +++ b/packages/types/src/codec/Result.ts @@ -1,7 +1,7 @@ // Copyright 2017-2021 @polkadot/types authors & contributors // SPDX-License-Identifier: Apache-2.0 -import type { Codec, Constructor, InterfaceTypes, Registry } from '../types'; +import type { Codec, Constructor, Registry } from '../types'; import { assert } from '@polkadot/util'; @@ -13,13 +13,13 @@ import { Enum } from './Enum'; * A Result maps to the Rust Result type, that can either wrap a success or error value */ export class Result extends Enum { - constructor (registry: Registry, Ok: Constructor | keyof InterfaceTypes, Err: Constructor | keyof InterfaceTypes, value?: unknown) { + constructor (registry: Registry, Ok: Constructor | string, Err: Constructor | string, value?: unknown) { // NOTE This is order-dependent, Ok (with index 0) needs to be first // eslint-disable-next-line sort-keys super(registry, { Ok, Err }, value); } - public static override with (Types: { Ok: Constructor | keyof InterfaceTypes; Err: Constructor | keyof InterfaceTypes }): Constructor> { + public static override with (Types: { Ok: Constructor | string; Err: Constructor | string }): Constructor> { return class extends Result { constructor (registry: Registry, value?: unknown) { super(registry, Types.Ok, Types.Err, value); diff --git a/packages/types/src/codec/Struct.ts b/packages/types/src/codec/Struct.ts index 665c7694a4..81d630aab1 100644 --- a/packages/types/src/codec/Struct.ts +++ b/packages/types/src/codec/Struct.ts @@ -2,13 +2,13 @@ // SPDX-License-Identifier: Apache-2.0 import type { CodecHash, Hash } from '../interfaces/runtime'; -import type { AnyJson, BareOpts, Codec, Constructor, ConstructorDef, InterfaceTypes, Registry } from '../types'; +import type { AnyJson, BareOpts, Codec, Constructor, ConstructorDef, Registry } from '../types'; import { assert, hexToU8a, isBoolean, isFunction, isHex, isObject, isU8a, isUndefined, stringCamelCase, stringify, u8aConcat, u8aToHex } from '@polkadot/util'; import { compareMap, decodeU8a, mapToTypeMap } from './utils'; -type TypesDef = Record>; +type TypesDef = Record>; /** @internal */ function decodeStructFromObject (registry: Registry, Types: ConstructorDef, value: any, jsonMap: Map): T { diff --git a/packages/types/src/codec/Tuple.spec.ts b/packages/types/src/codec/Tuple.spec.ts index 4baa41dad1..ef1ac95b99 100644 --- a/packages/types/src/codec/Tuple.spec.ts +++ b/packages/types/src/codec/Tuple.spec.ts @@ -51,7 +51,7 @@ describe('Tuple', (): void => { it('decodes properly from complex types', (): void => { const INPUT = '0xcc0200000000'; - const test = registry.createType('(u32, [u32; 0], u16)' as 'u32', INPUT); + const test = registry.createType('(u32, [u32; 0], u16)', INPUT); expect(test.encodedLength).toEqual(4 + 0 + 2); expect(test.toHex()).toEqual(INPUT); diff --git a/packages/types/src/codec/Tuple.ts b/packages/types/src/codec/Tuple.ts index b629effdbf..6c23d77eb7 100644 --- a/packages/types/src/codec/Tuple.ts +++ b/packages/types/src/codec/Tuple.ts @@ -1,7 +1,7 @@ // Copyright 2017-2021 @polkadot/types authors & contributors // SPDX-License-Identifier: Apache-2.0 -import type { AnyNumber, AnyString, AnyU8a, Codec, Constructor, InterfaceTypes, Registry } from '../types'; +import type { AnyNumber, AnyString, AnyU8a, Codec, Constructor, Registry } from '../types'; import { isHex, isU8a, stringify, u8aConcat, u8aToU8a } from '@polkadot/util'; @@ -14,8 +14,8 @@ type TupleConstructors = Constructor[] | { [index: string]: Constructor; }; -type TupleTypes = (Constructor | keyof InterfaceTypes)[] | { - [index: string]: Constructor | keyof InterfaceTypes; +type TupleTypes = (Constructor | string)[] | { + [index: string]: Constructor | string; }; /** @internal */ diff --git a/packages/types/src/codec/Vec.spec.ts b/packages/types/src/codec/Vec.spec.ts index 40b231f2cb..d0f8bb1967 100644 --- a/packages/types/src/codec/Vec.spec.ts +++ b/packages/types/src/codec/Vec.spec.ts @@ -2,7 +2,7 @@ // SPDX-License-Identifier: Apache-2.0 import type { PropIndex } from '../interfaces/democracy'; -import type { Codec, CodecTo } from '../types'; +import type { Codec, CodecTo, ITuple } from '../types'; import rpcMetadata from '@polkadot/types-support/metadata/static-substrate'; import { randomAsU8a } from '@polkadot/util-crypto'; @@ -11,7 +11,7 @@ import { createTypeUnsafe, TypeRegistry } from '../create'; import { GenericAccountId as AccountId } from '../generic'; import { Metadata } from '../metadata'; import { Text } from '../primitive'; -import { Tuple, Vec } from '.'; +import { Vec } from '.'; const registry = new TypeRegistry(); const metadata = new Metadata(registry, rpcMetadata); @@ -69,20 +69,19 @@ describe('Vec', (): void => { }); it('decodes a complex type via construction', (): void => { - const test = createTypeUnsafe(registry, 'Vec<(PropIndex, AccountId)>', [new Uint8Array([ + const test = createTypeUnsafe>>(registry, 'Vec<(PropIndex, AccountId)>', [new Uint8Array([ 4, 10, 0, 0, 0, 209, 114, 167, 76, 218, 76, 134, 89, 18, 195, 43, 160, 168, 10, 87, 174, 105, 171, 174, 65, 14, 92, 203, 89, 222, 232, 78, 47, 68, 50, 219, 79 ])]); - const first = (test as Vec)[0] as Tuple; - expect((first[0] as PropIndex).toNumber()).toEqual(10); - expect((first[1] as AccountId).toString()).toEqual('5GoKvZWG5ZPYL1WUovuHW3zJBWBP5eT8CbqjdRY4Q6iMaQua'); + expect(test[0][0].toNumber()).toEqual(10); + expect(test[0][1].toString()).toEqual('5GoKvZWG5ZPYL1WUovuHW3zJBWBP5eT8CbqjdRY4Q6iMaQua'); }); it('decodes a complex type via construction', (): void => { const INPUT = '0x08cc0200000000ce0200000001'; - const test = createTypeUnsafe(registry, 'Vec<(u32, [u32; 0], u16)>' as any, [INPUT]); + const test = createTypeUnsafe>(registry, 'Vec<(u32, [u32; 0], u16)>', [INPUT]); - expect((test as Vec).length).toEqual(2); + expect(test).toHaveLength(2); expect(test.toHex()).toEqual(INPUT); }); diff --git a/packages/types/src/codec/Vec.ts b/packages/types/src/codec/Vec.ts index 3951486ffd..33390e3c96 100644 --- a/packages/types/src/codec/Vec.ts +++ b/packages/types/src/codec/Vec.ts @@ -1,7 +1,7 @@ // Copyright 2017-2021 @polkadot/types authors & contributors // SPDX-License-Identifier: Apache-2.0 -import type { Codec, Constructor, InterfaceTypes, Registry } from '../types'; +import type { Codec, Constructor, Registry } from '../types'; import { assert, compactFromU8a, logger, u8aToU8a } from '@polkadot/util'; @@ -22,7 +22,7 @@ const l = logger('Vec'); export class Vec extends AbstractArray { private _Type: Constructor; - constructor (registry: Registry, Type: Constructor | keyof InterfaceTypes, value: Vec | Uint8Array | string | unknown[] = []) { + constructor (registry: Registry, Type: Constructor | string, value: Vec | Uint8Array | string | unknown[] = []) { const Clazz = typeToConstructor(registry, Type); super(registry, ...Vec.decodeVec(registry, Clazz, value)); @@ -55,7 +55,7 @@ export class Vec extends AbstractArray { return decodeU8a(registry, u8a.subarray(offset), new Array(length.toNumber()).fill(Type)) as T[]; } - public static with (Type: Constructor | keyof InterfaceTypes): Constructor> { + public static with (Type: Constructor | string): Constructor> { return class extends Vec { constructor (registry: Registry, value?: any[]) { super(registry, Type, value); diff --git a/packages/types/src/codec/VecFixed.ts b/packages/types/src/codec/VecFixed.ts index 679091f0ee..e59b0be4b7 100644 --- a/packages/types/src/codec/VecFixed.ts +++ b/packages/types/src/codec/VecFixed.ts @@ -1,7 +1,7 @@ // Copyright 2017-2021 @polkadot/types authors & contributors // SPDX-License-Identifier: Apache-2.0 -import type { Codec, Constructor, InterfaceTypes, Registry } from '../types'; +import type { Codec, Constructor, Registry } from '../types'; import { assert, compactToU8a, isHex, isU8a, u8aConcat } from '@polkadot/util'; @@ -36,7 +36,7 @@ function decodeVecFixed (registry: Registry, Type: Constructor< export class VecFixed extends AbstractArray { private _Type: Constructor; - constructor (registry: Registry, Type: Constructor | keyof InterfaceTypes, length: number, value: VecFixed | Uint8Array | string | any[] = [] as any[]) { + constructor (registry: Registry, Type: Constructor | string, length: number, value: VecFixed | Uint8Array | string | any[] = [] as any[]) { const Clazz = typeToConstructor(registry, Type); super(registry, ...decodeVecFixed(registry, Clazz, length, value)); @@ -44,7 +44,7 @@ export class VecFixed extends AbstractArray { this._Type = Clazz; } - public static with (Type: Constructor | keyof InterfaceTypes, length: number): Constructor> { + public static with (Type: Constructor | string, length: number): Constructor> { return class extends VecFixed { constructor (registry: Registry, value?: any[]) { super(registry, Type, length, value); diff --git a/packages/types/src/codec/utils/mapToTypeMap.ts b/packages/types/src/codec/utils/mapToTypeMap.ts index f2166e089b..16dd1ee8dd 100644 --- a/packages/types/src/codec/utils/mapToTypeMap.ts +++ b/packages/types/src/codec/utils/mapToTypeMap.ts @@ -1,14 +1,14 @@ // Copyright 2017-2021 @polkadot/types authors & contributors // SPDX-License-Identifier: Apache-2.0 -import type { Constructor, InterfaceTypes, Registry } from '../../types'; +import type { Constructor, Registry } from '../../types'; import { typeToConstructor } from './typeToConstructor'; /** * @description takes an input map of the form `{ [string]: string | Constructor }` and returns a map of `{ [string]: Constructor }` */ -export function mapToTypeMap (registry: Registry, input: Record): Record { +export function mapToTypeMap (registry: Registry, input: Record): Record { return Object .entries(input) .reduce((output: Record, [key, type]): Record => { diff --git a/packages/types/src/codec/utils/typeToConstructor.ts b/packages/types/src/codec/utils/typeToConstructor.ts index bff320fd2e..f2be2f4632 100644 --- a/packages/types/src/codec/utils/typeToConstructor.ts +++ b/packages/types/src/codec/utils/typeToConstructor.ts @@ -1,11 +1,11 @@ // Copyright 2017-2021 @polkadot/types authors & contributors // SPDX-License-Identifier: Apache-2.0 -import type { Codec, Constructor, InterfaceTypes, Registry } from '../../types'; +import type { Codec, Constructor, Registry } from '../../types'; import { isString } from '@polkadot/util'; -export function typeToConstructor (registry: Registry, type: keyof InterfaceTypes | Constructor): Constructor { +export function typeToConstructor (registry: Registry, type: string | Constructor): Constructor { return ( isString(type) ? registry.createClass(type) diff --git a/packages/types/src/create/createClass.ts b/packages/types/src/create/createClass.ts index 213c813a31..977f213824 100644 --- a/packages/types/src/create/createClass.ts +++ b/packages/types/src/create/createClass.ts @@ -2,8 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 import type { U8aBitLength, UIntBitLength } from '../codec/types'; -import type { Codec, Constructor, InterfaceTypes, Registry } from '../types'; -import type { FromReg, TypeDef } from './types'; +import type { Codec, Constructor, DetectConstructor, Registry } from '../types'; +import type { TypeDef } from './types'; import { assert, isNumber, isUndefined, stringify } from '@polkadot/util'; @@ -12,9 +12,8 @@ import { Bytes, Null } from '../primitive'; import { getTypeDef } from './getTypeDef'; import { TypeDefInfo } from './types'; -export function createClass (registry: Registry, type: K): Constructor> { - // eslint-disable-next-line @typescript-eslint/no-use-before-define - return getTypeClass>( +export function createClass (registry: Registry, type: K): DetectConstructor { + return getTypeClass( registry, registry.isLookupType(type) ? registry.lookup.getTypeDef(type) @@ -22,21 +21,6 @@ export function createClass ); } -// An unsafe version of the `createType` below. It's unsafe because the `type` -// argument here can be any string, which, if it cannot be parsed, it will yield -// a runtime error. -export function ClassOfUnsafe (registry: Registry, name: K): Constructor> { - return createClass(registry, name); -} - -// alias for createClass -export function ClassOf (registry: Registry, name: K): Constructor { - // TS2589: Type instantiation is excessively deep and possibly infinite. - // The above happens with as Constructor; - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return ClassOfUnsafe(registry, name) as any; -} - function getSubDefArray (value: TypeDef): TypeDef[] { assert(value.sub && Array.isArray(value.sub), () => `Expected subtype as TypeDef[] in ${stringify(value)}`); @@ -49,24 +33,24 @@ function getSubDef (value: TypeDef): TypeDef { return value.sub; } -function getSubType (value: TypeDef): keyof InterfaceTypes { - return getSubDef(value).type as keyof InterfaceTypes; +function getSubType (value: TypeDef): string { + return getSubDef(value).type; } // create a maps of type string constructors from the input -function getTypeClassMap (value: TypeDef): Record { - const result: Record = {}; +function getTypeClassMap (value: TypeDef): Record { + const result: Record = {}; - return getSubDefArray(value).reduce>((result, sub) => { - result[sub.name as string] = sub.type as keyof InterfaceTypes; + return getSubDefArray(value).reduce>((result, sub) => { + result[sub.name as string] = sub.type; return result; }, result); } // create an array of type string constructors from the input -function getTypeClassArray (value: TypeDef): (keyof InterfaceTypes)[] { - return getSubDefArray(value).map(({ type }) => type as keyof InterfaceTypes); +function getTypeClassArray (value: TypeDef): string[] { + return getSubDefArray(value).map(({ type }) => type); } function createInt ({ displayName, length }: TypeDef, Clazz: typeof Int | typeof UInt): Constructor { @@ -184,7 +168,7 @@ const infoMapping: Record C [TypeDefInfo.VecFixed]: (registry: Registry, { displayName, length, sub }: TypeDef): Constructor => { assert(isNumber(length) && !isUndefined(sub), 'Expected length & type information for fixed vector'); - const subType = (sub as TypeDef).type as keyof InterfaceTypes; + const subType = (sub as TypeDef).type; return ( subType === 'u8' diff --git a/packages/types/src/create/createType.ts b/packages/types/src/create/createType.ts index 638ddf2fca..20f56d41e4 100644 --- a/packages/types/src/create/createType.ts +++ b/packages/types/src/create/createType.ts @@ -2,8 +2,8 @@ // SPDX-License-Identifier: Apache-2.0 import type { Bytes } from '../primitive/Bytes'; -import type { Codec, Constructor, InterfaceTypes, Registry } from '../types'; -import type { CreateOptions, FromReg } from './types'; +import type { Codec, Constructor, DetectCodec, Registry } from '../types'; +import type { CreateOptions } from './types'; import { assert, isHex, isU8a, u8aEq, u8aToHex, u8aToU8a } from '@polkadot/util'; @@ -12,7 +12,7 @@ import { createClass } from './createClass'; // With isPedantic, actually check that the encoding matches that supplied. This // is much slower, but verifies that we have the correct types defined -function checkInstance (created: FromReg, value: Uint8Array): void { +function checkInstance (created: Codec, value: Uint8Array): void { const u8a = created.toU8a(); const rawType = created.toRawType(); @@ -26,7 +26,7 @@ function checkInstance (created: FromReg, value: Uint8Array): voi ); } -function checkPedantic (created: FromReg, [value]: unknown[], isPedantic = false): void { +function checkPedantic (created: Codec, [value]: unknown[], isPedantic = false): void { if (isPedantic) { if (isU8a(value)) { checkInstance(created, value); @@ -38,7 +38,7 @@ function checkPedantic (created: FromReg, [value]: unknown[], isP // Initializes a type with a value. This also checks for fallbacks and in the cases // where isPedantic is specified (storage decoding), also check the format/structure -function initType (registry: Registry, Type: Constructor>, params: unknown[] = [], { blockHash, isOptional, isPedantic }: CreateOptions = {}): FromReg { +function initType (registry: Registry, Type: Constructor, params: unknown[] = [], { blockHash, isOptional, isPedantic }: CreateOptions = {}): DetectCodec { const created = new (isOptional ? Option.with(Type) : Type)(registry, ...params); checkPedantic(created, params, isPedantic); @@ -54,8 +54,8 @@ function initType (registry: // An unsafe version of the `createType` below. It's unsafe because the `type` // argument here can be any string, which, when it cannot parse, will yield a // runtime error. -export function createTypeUnsafe (registry: Registry, type: K, params: unknown[] = [], options: CreateOptions = {}): T { - let Clazz: Constructor> | null = null; +export function createTypeUnsafe (registry: Registry, type: K, params: unknown[] = [], options: CreateOptions = {}): DetectCodec { + let Clazz: Constructor | null = null; let firstError: Error | null = null; try { @@ -85,6 +85,6 @@ export function createTypeUnsafe (registry: Registry, type: K, ...params: unknown[]): InterfaceTypes[K] { - return createTypeUnsafe(registry, type, params); +export function createType (registry: Registry, type: K, ...params: unknown[]): DetectCodec { + return createTypeUnsafe(registry, type, params); } diff --git a/packages/types/src/create/getTypeDef.spec.ts b/packages/types/src/create/getTypeDef.spec.ts index 01d09863f4..47357fca57 100644 --- a/packages/types/src/create/getTypeDef.spec.ts +++ b/packages/types/src/create/getTypeDef.spec.ts @@ -512,7 +512,7 @@ describe('getTypeDef', (): void => { } }); - const raw = registry.createType('Recursive' as 'u32').toRawType(); + const raw = registry.createType('Recursive').toRawType(); expect( getTypeDef(raw) diff --git a/packages/types/src/create/registry.ts b/packages/types/src/create/registry.ts index 1a3cfdfc18..cb6411fb12 100644 --- a/packages/types/src/create/registry.ts +++ b/packages/types/src/create/registry.ts @@ -5,7 +5,7 @@ import type { ExtDef } from '../extrinsic/signedExtensions/types'; import type { ChainProperties, CodecHash, DispatchErrorModule, Hash, MetadataLatest, PortableRegistry, SiLookupTypeId } from '../interfaces/types'; -import type { CallFunction, Codec, CodecHasher, Constructor, InterfaceTypes, RegisteredTypes, Registry, RegistryError, RegistryTypes } from '../types'; +import type { CallFunction, Codec, CodecHasher, Constructor, DetectCodec, DetectConstructor, InterfaceTypes, RegisteredTypes, Registry, RegistryError, RegistryTypes } from '../types'; import type { CreateOptions } from './types'; import { assert, assertReturn, BN_ZERO, formatBalance, isFunction, isString, isU8a, logger, stringCamelCase, stringify, u8aToHex } from '@polkadot/util'; @@ -241,22 +241,21 @@ export class TypeRegistry implements Registry { /** * @describe Creates an instance of the class */ - public createClass (type: K): Constructor { - // eslint-disable-next-line @typescript-eslint/no-unsafe-return - return createClass(this, type) as any; + public createClass (type: K): DetectConstructor { + return createClass(this, type); } /** * @description Creates an instance of a type as registered */ - public createType (type: K, ...params: unknown[]): InterfaceTypes[K] { + public createType (type: K, ...params: unknown[]): DetectCodec { return createTypeUnsafe(this, type, params); } /** * @description Creates an instance of a type as registered */ - public createTypeUnsafe (type: K, params: unknown[], options?: CreateOptions): T { + public createTypeUnsafe (type: K, params: unknown[], options?: CreateOptions): DetectCodec { return createTypeUnsafe(this, type, params, options); } @@ -284,13 +283,13 @@ export class TypeRegistry implements Registry { return assertReturn(this.#metadataEvents[hexIndex], `findMetaEvent: Unable to find Event with index ${hexIndex}/[${eventIndex.toString()}]`); } - public get (name: string, withUnknown?: boolean): Constructor | undefined { + public get (name: K, withUnknown?: boolean): DetectConstructor | undefined { let Type = this.#classes.get(name); // we have not already created the type, attempt it if (!Type) { const definition = this.#definitions.get(name); - let BaseType: Constructor | undefined; + let BaseType: Constructor | undefined; // we have a definition, so create the class now (lazily) if (definition) { @@ -312,7 +311,7 @@ export class TypeRegistry implements Registry { } } - return Type as Constructor; + return Type as DetectConstructor; } public getChainProperties (): ChainProperties | undefined { @@ -335,12 +334,12 @@ export class TypeRegistry implements Registry { return this.#knownTypes?.typesBundle?.spec?.[specName]?.instances?.[moduleName]; } - public getOrThrow (name: string, msg?: string): Constructor { - return assertReturn(this.get(name), msg || `type ${name} not found`); + public getOrThrow (name: K, msg?: string): DetectConstructor { + return assertReturn(this.get(name), msg || `type ${name} not found`); } - public getOrUnknown (name: string): Constructor { - return this.get(name, true) as Constructor; + public getOrUnknown (name: K): DetectConstructor { + return this.get(name, true) as DetectConstructor; } public getSignedExtensionExtra (): Record { diff --git a/packages/types/src/create/types.ts b/packages/types/src/create/types.ts index 87a2e63915..7285db7d66 100644 --- a/packages/types/src/create/types.ts +++ b/packages/types/src/create/types.ts @@ -1,13 +1,6 @@ // Copyright 2017-2021 @polkadot/types authors & contributors // SPDX-License-Identifier: Apache-2.0 -import type { Codec, InterfaceTypes } from '../types'; - -// Type which says: if `K` is in the InterfaceTypes, then return InterfaceTypes[K], else fallback to T -export type FromReg = K extends keyof InterfaceTypes - ? InterfaceTypes[K] - : T; - export enum TypeDefInfo { BTreeMap, BTreeSet, diff --git a/packages/types/src/extrinsic/Extrinsic.ts b/packages/types/src/extrinsic/Extrinsic.ts index 02fc84ca09..664d556353 100644 --- a/packages/types/src/extrinsic/Extrinsic.ts +++ b/packages/types/src/extrinsic/Extrinsic.ts @@ -4,7 +4,7 @@ import type { EcdsaSignature, Ed25519Signature, ExtrinsicUnknown, ExtrinsicV4, Sr25519Signature } from '../interfaces/extrinsics'; import type { FunctionMetadataLatest } from '../interfaces/metadata/types'; import type { Address, Balance, Call, Index } from '../interfaces/runtime'; -import type { AnyJson, AnyTuple, AnyU8a, ArgsDef, CallBase, ExtrinsicPayloadValue, IExtrinsic, IKeyringPair, IMethod, InterfaceTypes, Registry, SignatureOptions } from '../types'; +import type { AnyJson, AnyTuple, AnyU8a, ArgsDef, CallBase, ExtrinsicPayloadValue, IExtrinsic, IKeyringPair, IMethod, Registry, SignatureOptions } from '../types'; import type { GenericExtrinsicEra } from './ExtrinsicEra'; import type { ExtrinsicValueV4 } from './v4/Extrinsic'; @@ -24,7 +24,7 @@ interface CreateOptions { type ExtrinsicVx = ExtrinsicV4; type ExtrinsicValue = ExtrinsicValueV4; -const VERSIONS: (keyof InterfaceTypes)[] = [ +const VERSIONS = [ 'ExtrinsicUnknown', // v0 is unknown 'ExtrinsicUnknown', 'ExtrinsicUnknown', @@ -183,7 +183,7 @@ export class GenericExtrinsic extends ExtrinsicBa // we cast here since the VERSION definition is incredibly broad - we don't have a // slice for "only add extrinsic types", and more string definitions become unwieldy - return registry.createType(type, value, { isSigned, version }) as ExtrinsicVx; + return registry.createType(type, value, { isSigned, version }); } /** @internal */ diff --git a/packages/types/src/extrinsic/ExtrinsicPayload.ts b/packages/types/src/extrinsic/ExtrinsicPayload.ts index 39b36b1b94..f2238f0bb2 100644 --- a/packages/types/src/extrinsic/ExtrinsicPayload.ts +++ b/packages/types/src/extrinsic/ExtrinsicPayload.ts @@ -3,7 +3,7 @@ import type { ExtrinsicPayloadV4 } from '../interfaces/extrinsics'; import type { Balance, Hash, Index } from '../interfaces/runtime'; -import type { AnyJson, BareOpts, ExtrinsicPayloadValue, IKeyringPair, InterfaceTypes, Registry } from '../types'; +import type { AnyJson, BareOpts, ExtrinsicPayloadValue, IKeyringPair, Registry } from '../types'; import { u8aToHex } from '@polkadot/util'; @@ -21,7 +21,7 @@ interface ExtrinsicPayloadOptions { // all our known types that can be returned type ExtrinsicPayloadVx = ExtrinsicPayloadV4; -const VERSIONS: (keyof InterfaceTypes)[] = [ +const VERSIONS = [ 'ExtrinsicPayloadUnknown', // v0 is unknown 'ExtrinsicPayloadUnknown', 'ExtrinsicPayloadUnknown', @@ -46,7 +46,7 @@ export class GenericExtrinsicPayload extends Base { return value._raw; } - return registry.createType(VERSIONS[version] || VERSIONS[0], value, { version }) as ExtrinsicPayloadVx; + return registry.createType(VERSIONS[version] || VERSIONS[0], value, { version }); } /** diff --git a/packages/types/src/metadata/util/toCallsOnly.ts b/packages/types/src/metadata/util/toCallsOnly.ts index 7efb10ec1f..3a5a0035de 100644 --- a/packages/types/src/metadata/util/toCallsOnly.ts +++ b/packages/types/src/metadata/util/toCallsOnly.ts @@ -26,7 +26,7 @@ function mapCalls (registry: Registry, _calls: Option>' as any, + 'Option>', calls ? calls.map(({ args, docs, name }) => registry.createType('FunctionMetadataLatest', { @@ -36,7 +36,7 @@ function mapCalls (registry: Registry, _calls: Option>; + ); } /** @internal */ diff --git a/packages/types/src/types/registry.ts b/packages/types/src/types/registry.ts index d531b090cf..e3be969506 100644 --- a/packages/types/src/types/registry.ts +++ b/packages/types/src/types/registry.ts @@ -17,6 +17,12 @@ import type { DefinitionRpc, DefinitionRpcSub } from './definitions'; // eslint-disable-next-line @typescript-eslint/no-empty-interface export interface InterfaceTypes { } +export type DetectCodec = K extends keyof InterfaceTypes + ? InterfaceTypes[K] + : T; + +export type DetectConstructor = Constructor>; + export type CodecHasher = (data: Uint8Array) => Uint8Array; export interface ChainUpgradeVersion { @@ -119,16 +125,16 @@ export interface Registry { isLookupType (value: string): boolean; createLookupType (lookupId: SiLookupTypeId | number): string; - createClass (type: K): Constructor; - createType (type: K, ...params: unknown[]): InterfaceTypes[K]; - createTypeUnsafe (type: K, params: unknown[], options?: CreateOptions): T; - get (name: string, withUnknown?: boolean): Constructor | undefined; + createClass (type: K): DetectConstructor; + createType (type: K, ...params: unknown[]): DetectCodec; + createTypeUnsafe (type: K, params: unknown[], options?: CreateOptions): DetectCodec; + get (name: K, withUnknown?: boolean): DetectConstructor | undefined; getChainProperties (): ChainProperties | undefined; getClassName (clazz: Constructor): string | undefined; getDefinition (typeName: string): string | undefined; getModuleInstances (specName: string, moduleName: string): string[] | undefined; - getOrThrow (name: string, msg?: string): Constructor; - getOrUnknown (name: string): Constructor; + getOrThrow (name: K, msg?: string): DetectConstructor; + getOrUnknown (name: K): DetectConstructor; setKnownTypes (types: RegisteredTypes): void; getSignedExtensionExtra (): Record; getSignedExtensionTypes (): Record;