What's the right way to model an object property bag type (aka "record") in TS where some property names are alternate names (aka "aliases") for other properties? In particular we want to make VSCode aware of the aliasing so that it will only suggest (in IntelliSense autocomplete lists) the "main" property names and not the aliases, but we also don't want the TS compiler to fail if users manually type in aliases.
Here's more background: We're working on a .d.ts for a JS library which includes functions that accept time-like literals like {hour: 12, minute: 30, second: 0}. The library also accepts plural variants of these literals' properties e.g. {hours: 12, minutes: 30, seconds: 0}. Using the plural variants is not a best practice (and probably won't be documented beyond a quick note that they're allowed). But using these plural strings won't crash either.
What will crash is the case where the same unit is specified with both variants: e.g. {hour: 12, hours: 12}.
How should we model this type in TS?
Our goals:
- Hide the "wrong" variants from IDE autocomplete. I assumed that I assume that the JSDoc
ignoretag would be useful for this purpose, but it's not listed in the supported tags list in the TS docs and it doesn't seem to do anything in VSCode. - Allow the "wrong" variants without a TS compiler error.
- Produce a TS compiler error if both singular and plural variants of the same property are included in the same object literal.
- Ideally, also produce a compiler error if a smaller unit is present without the corresponding larger unit. For example,
{hour: 10, second: 30}should produce an error. That said, I'm not sure this is possible in TS because of how union types work. - Ideally, a mix of the singular and plural variants should also produce a compiler error even if the property's alias is not present, e.g.
{hours: 10, minute: 5}. It's also OK if this error is not flagged by TS because it's a rare mistake than the "2 variants of same unit" case noted above. - Ideally (this is optional because I suspect that it may not be possible), the plural variants would show an informational-level IDE warning (a light-blue squiggly line in VSCode) to encourage users to choose the correct variant instead of the wrong one, but without breaking compilation.
What's the recommended way to model these literals in TypeScript and/or JSDoc to achieve this desired behavior, or at least a subset of it?
Here's the plain type including both variants. This declaration doesn't exhibit any of the desired behavior above.
type Time = {
hour?: number;
minute?: number;
second?: number;
hours?: number;
minutes?: number;
seconds?: number;
};
JSDoc's @alias tag seems closest to our intent, but it doesn't seem to do anything in VSCode and it doesn't exempt the plural variants from autocomplete. I'm also unsure if @alias is intended to handle the case where the alias is pointing to a sibling member. All the examples in the JSDoc manual linked above are referring to cases where a member is defined with one name but used at runtime with another name, e.g. static class functions that are used with a class name prefix. I didn't see any examples where @alias was used to mirror another existing sibling property.
We could use JSDoc @deprecated but that implies that the values used to be OK but now aren't, which isn't quite true. But it does supply a message to alert users to use the other variant. This seems useful.
JSDoc's @ignore tag also seems like it might help, but it also doesn't seem to do anything in VSCode and it also doesn't exempt the plural variants from autocomplete.

