Skip to content

Strongly typed sprintf #15

@swissspidy

Description

@swissspidy

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. 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 printf<T extends string>(format: T, ...values: Values<T>): string;

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

Note: this doesn't support named arguments yet.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions