Closed Yuripetusko closed 2 years ago
Ok, so generally it should show an AnyNumber
, the reason being that any number input can take one of the following - number, BN, BigInt, hex, decimal string. So where number are required, if you pass any of those, it will convert it to whatever is needed to communicate with the runtime.
So at worst (and I'm not advocating littering the code like this), do `call(123 as any, ...)
The right solution is to ensure the typegen handles this case correctly. For this, the chain (and or static metadata) as well as the actual type to look at would be great to see what can be done to ensure typegen does it the way it is supposed to.
The types for our pallets are a mess in general :D But it's all WIP still.
For example let's take z
field as example
It's set as primitive here first https://github.com/rmrk-team/rmrk-substrate/blob/11662cb0e543b2ed91445b1497abc036a1db4b37/traits/src/lib.rs#L34
Then used on this trait here https://github.com/rmrk-team/rmrk-substrate/blob/11662cb0e543b2ed91445b1497abc036a1db4b37/traits/src/part.rs#L16
And finally accepted as an argument here: https://github.com/rmrk-team/rmrk-substrate/blob/11662cb0e543b2ed91445b1497abc036a1db4b37/pallets/rmrk-equip/src/functions.rs#L79
You can see metadata here https://github.com/rmrk-team/rmrk-substrate-js/blob/master/tools/rmrk-substrate-metadata.json
And type definitions that I am trying to create here: https://github.com/rmrk-team/rmrk-substrate-js/tree/master/libs/rmrk-substrate-api/src/interfaces/rmrkEquip
I am not a rust dev FYI, I am a fullstack dev who is trying to write a UI/scripts to use these pallets through polkadot.js api
404 for me on the metadata link (I need this to generate against to be able to test)
404 for me on the metadata link (I need this to generate against to be able to test)
Sorry forgot it's private. here's gist
https://gist.github.com/Yuripetusko/8fec250d828dd92747a73f6ec51d3ec2
Perfect, ty.
So the Fixed part is the following -
/** @name RmrkTraitsPartFixedPart (132) */
export interface RmrkTraitsPartFixedPart extends Struct {
readonly id: u32;
readonly z: u32;
readonly src: Bytes;
}
Which is all fine since that is the actual type definition, so it will be "tight", i.e. when you do part.z
it will return a u32.
Where your issue lies is the following -
createBase: AugmentedSubmittable<(
baseType: Bytes | string | Uint8Array,
symbol: Bytes | string | Uint8Array,
parts: Vec<RmrkTraitsPartPartType> | (RmrkTraitsPartPartType | { FixedPart: any } | { SlotPart: any } | string | Uint8Array)[]
) => SubmittableExtrinsic<ApiType>, [Bytes, Bytes, Vec<RmrkTraitsPartPartType>]>;
So here the Struct is not expanded, but at the same time it would allow you to pass in anything. So this would be all ok, even for the type-checker -
api.tx.rmrkEquip.createBase(
// base
'something',
// symbol
'LEET',
// parts
[
// fixed version
{ fixedPart: { id: 1, z: 2, src: 'anything' },
// slot version
{ slotPart: { id: 3, z: 4, ... } }
]
...
So in none of these cases should it make TS complain at all. (Obviously it would be great if the typegen doesn't create any
for all these enum definitions and expands them fully... it is one of those code TODO
s that is need of elbow grease to get done)
Thanks I see, I was confused a bit in few places in my code, but additionally I was trying to use types created from definitions to have a separate function that generates Vec<RmrkTraitsPartPartType>
before passing it to createBase
I cannot do like createBaseParts: (): RmrkTraitsPartPartType[] => {...}
as then the types are not the same as createBase
arguments as RmrkTraitsPartPartType
will not have the option with any
I think also if functions arguments were exported as separate types that would help this cause too. For example in createBase
last argument would be export type CreateBasePartsArgument = Vec<RmrkTraitsPartPartType> | (RmrkTraitsPartPartType | { FixedPart: any } | { SlotPart: any } | string | Uint8Array)[]
that would solve my problem and I could easily use this type in my function.
TS does allow you to extract parameters for any function. On a transfer (I used something with an enum to show the approach) -
const createTransfer: () => Parameters<typeof api.tx.balances.transfer> => {... };
The signature above, from VSCode, is
const createTransfer: () => [dest: string | MultiAddress | Uint8Array | {
Id: any;
} | {
Index: any;
} | {
Raw: any;
} | {
Address32: any;
} | {
Address20: any;
}, value: Compact<u128> | AnyNumber]
Which means I can do -
const createTransfer: () => Parameters<typeof api.tx.balances.transfer> => [{ id: '5F...' }, 123];
Then to create/call -
await api.tx.balances.transfer(...createTransfer());
PS: I did look at what it would take to extract the enum correctly and it is not quite straight-forward, the same applies to structs. It goes slightly haywire with the nested stuff. Not impossible at all, you just need to have your wits with you to get it non-any.
Thanks, didn't know or forgot about the Parameter utility type. That will do for now for my case, but yeah, would be great to hear a more strict generated types here sometimes in future if possible
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue if you think you have a related problem or query.
We have a custom-built pallet that expects one of it's argument as
u32
, I can not find a way to pass a type that typescript would accept, not sure how to create a u32 type from the client.In some other pallets I see that u32 is often also paired with AnyNumber when doing type- but not in our case, (it's not a first-level argument, but a nested struct of an argument) https://github.com/rmrk-team/rmrk-substrate-js/blob/master/libs/rmrk-substrate-api/src/interfaces/rmrkEquip/types.ts#L20
I tried
new u32
but it expects a whole registry,numberToU8a
etc. But typescript complains still