Description
Motivation
Currently, string localization is done by calling a method
vscode.l10n.t('Hello {0}!' name);
This mirrors what we do in core, however, this is a little error-prone. There's no validation in that string to ensure that replacement are done correctly, that all replacement arguments are used, or that enough replacement arguments are provided to satisfy the string. This is what initially inspired me 🙈
Proposal
We propose adding an overload to vscode.l10n.t
that allows it to be used with tagged template literals. With tagged literalls, developers use a template literal as they "normally would", but prepend it with the method call
vscode.l10n.t`Hello ${name}!`
The associated definition for t()
would gain an overload:
export namespace l10n {
/**
* Marks a string for localization. If a localized bundle is available for the language specified by
* {@link env.language} and the bundle has a localized value for this message, then that localized
* value will be returned (with injected {@link args} values for any templated values).
*
* This signature is for use with tagged template literals. The more verbose object-based
* call should be used if comments are required.
*
* @example
* ```
* vscode.l10n.t`Hello ${name}!`
* ```
*
* @param message - String message components.
* @param args - Replacement components in the string.
* @returns localized string with injected arguments.
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals#tagged_templates
*/
export function t(parts: TemplateStringsArray, ...args: Array<string | number | boolean>): string;
Tagged template literals are an ES5 feature, and we already use ES6 features (such as Symbol.iterator
), so this does not introduce any new lib
/target
constraints.
Previously we haven't been big fans of adding "convenience" APIs such as this to the extension host API, but I think this might warrant some deviation since we force that this specific method is used (and not wrapped) in the localization extraction pipeline.
Alternatives
An alternative way to gain the same level of safety would be to use TS' template literal types to enforce argument placement. However, this lacks the ergonomic benefits of template literals, and would introduce previously unseen levels of type acrobatics to vscode.d.ts. Our extension host api is not a venue for Cirque du TypeScript.
Activity