Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: improve use of AssetKind type #4736

Merged
merged 4 commits into from
Mar 10, 2022
Merged

Conversation

turadg
Copy link
Member

@turadg turadg commented Mar 4, 2022

no-ticket, pulled out of #4732 in support of #3788

Description

Our current types for AssetKind have these deficiencies:

  • the default assetKind wasn't being picked up so to get it you'd have to pass it in like AmountMath.makeEmpty(runBrand, 'nat')
  • didn't type the brand, issuer, mint, etc that are linked to the Amount's kind, resulting in more casting than needed
  • when an annotation was needed, it was like Amount<NatValue>, more verbose than necessary.

This relies on parameterizing assetKind instead of assetValue. That type parameter applies to many other types and doesn't require importing a type in order to use because it's a string literal. E.g. nat instead of NatValue type. There's no risk of typos because the type parameter K must be a subtype of AssetKind which is the union of 'nat' | 'set' | 'copySet' | 'copyBag', so if someone were to type any string other than one of those four it would be a type failure. ( There may be an aesthetic argument to use AssetKind.NAT (const) but it would be more verbose without any safety benefit: Amount<AssetKind.NAT>.) A suggestion to use Amount<NAT> would be no more verbose and a little cleaner but then you'd have to define or import NAT in the file you're typing that.

Security Considerations

--

Documentation Considerations

--

Testing Considerations

tsc

Copy link
Member

@dckc dckc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please keep thie IssuerKit type spelled out as discussed below.

And unless we can write 'nat' as NAT, I can't speak for @erights and @Chris-Hibbert on this.

* V extends CopySetValue ? 'copySet' :
* V extends CopyBagValue ? 'copyBag' :
* never}
* @type {(value: V) => AssetKindForValue<V>}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general, an asset kind determines a value type, but not the other way around. We could have another assetkind that uses bigint values but uses mod p math or some such. The mapping is currently invertible, so I guess this is OK, but it gives me pause.

* @param {Amount<V>} rightAmount
* @template {AssetKind} [K=AssetKind]
* @param {Amount<K>} leftAmount
* @param {Amount<K>} rightAmount
* @param {Brand | undefined} brand
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @param {Brand | undefined} brand
* @param {Brand<K> | undefined} brand

Pinning down things like the kind is the reason to supply the optional brand.

* @param {Amount<V>} rightAmount
* @template {AssetKind} [K=AssetKind]
* @param {Amount<K>} leftAmount
* @param {Amount<K>} rightAmount
* @param {Brand=} brand
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @param {Brand=} brand
* @param {Brand<K>=} brand

* @param {Amount<V>} rightAmount
* @template {AssetKind} [K=AssetKind]
* @param {Amount<K>} leftAmount
* @param {Amount<K>} rightAmount
* @param {Brand=} brand
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @param {Brand=} brand
* @param {Brand<K>=} brand

* @param {Amount<V>} rightAmount
* @template {AssetKind} [K=AssetKind]
* @param {Amount<K>} leftAmount
* @param {Amount<K>} rightAmount
* @param {Brand=} brand
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @param {Brand=} brand
* @param {Brand<K>=} brand

* @property {Brand} brand
* @property {V} value
* @property {Brand<K>} brand
* @property {AssetValueForKind<K>} value
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

spif!

@@ -58,6 +58,21 @@
*/

/**
* @template {AssetKind} K
* @typedef {K extends 'nat' ? NatValue: K extends 'set' ? SetValue: K extends 'copySet' ? CopySetValue: K extends 'copyBag' ? CopyBagValue : never} AssetValueForKind
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stick to 80 columns, please?

*
* `displayInfo` gives information to UI on how to display the amount.
*
* @typedef {Object} IssuerKit
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As noted above, please leave this IssuerKit type spelled out for now.

I'm all for moving the MakeIssuerKit stuff by the function code.

Copy link
Member Author

@turadg turadg Mar 4, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We discussed offline.

The decision rests on whether IssuerKit is can be made by multiple functions. If so it's an interface and needs its own type declaration. If not, it's like a class constructor and should use ReturnType.

So far nothing else creates objects like this.

* @param {ERef<VirtualPurseController>} vpc the controller that represents the
* "other side" of this purse.
* @param {{ issuer: ERef<Issuer>, brand: Brand, mint?: ERef<Mint>,
* escrowPurse?: ERef<Purse> }} kit
* the contents of the issuer kit for "us".
*
comes close but is not compatible.

We defer to @erights on whether IssuerKit will be instantiated by other functions and I'm removing that change from this PR so that it doesn't need his review to land.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My concern here is mis-placed. Issuer is the thing that is interface-like that's important to keep spelled out.

Comment on lines +13 to +14
* @param {Amount<'nat'>} debtAmount
* @param {Amount<'nat'>} collateralAmount
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* @param {Amount<'nat'>} debtAmount
* @param {Amount<'nat'>} collateralAmount
* @param {Amount<NAT>} debtAmount
* @param {Amount<NAT>} collateralAmount

If there is not a straightforward way to arrange this, then I can't speak for @Chris-Hibbert and @erights in approving tihs.

Copy link
Member Author

@turadg turadg Mar 4, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This can totally be done, by defining const NAT = 'nat' but since NAT is 'nat' then I think what the user sees in an IDE or type error will still be 'nat'.

* @property {AssetKind} assetKind
* @property {Brand<K>} brand
* @property {Issuer<K>} issuer
* @property {K} assetKind
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this answers one of my earlier questions about constraining assetKind to match brand.

@turadg turadg requested a review from dckc March 10, 2022 16:34
Copy link
Member

@dckc dckc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's go for it!

@turadg turadg force-pushed the ta/type-brand-assetKind branch from 23dc662 to 0857866 Compare March 10, 2022 18:10
@turadg turadg added the automerge:squash Automatically squash merge label Mar 10, 2022
@mergify mergify bot merged commit b46c722 into master Mar 10, 2022
@mergify mergify bot deleted the ta/type-brand-assetKind branch March 10, 2022 18:25
dtribble pushed a commit that referenced this pull request Mar 13, 2022
* chore: fix types for Amount kind

* fixup! chore: fix types for Amount kind

* fixup! chore: fix types for Amount kind
Comment on lines -296 to -302
/**
* @callback MintPayment
*
* Creates a new Payment containing newly minted amount.
*
* @param {Amount} newAmount
* @returns {Payment}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this type disappeared in the refactor?

* @property {() => Issuer} getIssuer Gets the Issuer for this mint.
* @property {MintPayment} mintPayment
* @property {() => Issuer<K>} getIssuer Gets the Issuer for this mint.
* @property {MintPayment<K>} mintPayment
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MintPayment used here has no declaration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
automerge:squash Automatically squash merge
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants