Skip to content

I18N: Strongly typed sprintf #52985

@swissspidy

Description

@swissspidy

What problem does this address?

I just stumbled upon https://hacklewayne.com/a-truly-strongly-typed-printf-in-typescript and was wondering whether a solution like this could be considered for @tannin/sprintf.

Right now with the existing JSDoc every arg needs to be a string, when in fact the values will be cast to ints and floats anyway depending on the format.

What is your proposed solution?

A strongly typed implementation could make this more robust.

This would also help catch issues where the number of arguments doesn't match the number of placeholders.

From that article:

type Specifiers = {
    's': string,
    'd': number,
    'b': boolean,
    'D': Date
};

type Spec = keyof Specifiers;

type Values<T extends string> = 
    T extends `${infer _}%${infer K}${infer Rest}`
    ? K extends Spec
        ? [ Specifiers[K], ...Values<Rest> ]
        : Values<`${K}${Rest}`>
    : [];

declare function sprintf<T extends string>(format: T, ...values: Values<T>): string;

sprintf('this is a %s and it is %d %wyears old, right?%b %D %i %f', 'Hackle', 20, true, new Date()); // ok
sprintf('Hello %s', 'John'); // ok
sprintf('Hello %s', 'John', 'Doe'); // not ok, too many arguments
sprintf('Hello %s', false); // not ok, wrong type

Note: this doesn't support named arguments yet.

Related

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions