Replace multiple specific strings in typescript type

  Kiến thức lập trình

I’m looking for a way of replacing keys of a type when it contains the key of another.
I essentially want to do this to map up replacements which I have in another method. We have a large number of objects all in snake case being prettified for display. One of the steps is the replacement of specific keys.

Currently I’m doing:

type Replacements = {
    abc: 'cba';
    bcd: 'dcb';
};

type Test = {
    bcd: string;
    aabca: string;
};

type ReplaceKeys<R extends Record<string, string>, T extends Record<string, unknown>> = {
    [K in keyof T as K extends keyof R ? R[K] : K]: T[K];
  };
type Replaced = ReplaceKeys<Replacements, Test>;

Which gives me this type as expected:

type Replaced = {
    dcb: string;
    aabca: string;
}

However I’m wondering if there’s a way of replacing keys that are contained. I’ve tried creating a type to do the job:

type ReplaceKeysInferred<
    R extends Record<string, string>,
    T extends Record<string, unknown>,
> = {
    [K in keyof T as K extends `${infer A}${infer RKey extends keyof R & string}${infer B}`
        ? `${A}${R[RKey]}${B}`
        : K]: T[K];
};

type ReplacedInferred = ReplaceKeysInferred<Replacements, Test>;

However the type returned doesn’t contain any replacements:

type ReplacedInferred = {
    bcd: string;
    aabca: string;
}

Not sure where I’m going wrong.

Edit:
I’ve also tried:

type ReplaceKeysInferred<
    R extends Record<string, string>,
    T extends Record<string, unknown>,
> = {
    [K in keyof T as K extends `${infer A}${infer RKey}${infer B}`
        ? RKey extends keyof R
            ? `${A}${R[RKey]}${B}`
            : K
        : K]: T[K];
};

Which is essentially an extra step on the first type. This works the same as the first type giving back:

type ReplacedInferred = {
    bcd: string;
    aabca: string;
}

Which still isn’t replacing any contained strings.

1

LEAVE A COMMENT