Home > database >  Using a inferred type, which is a valid key type, as the name of a property in a computed interface
Using a inferred type, which is a valid key type, as the name of a property in a computed interface

Time:10-06

I currently have this:

export class UnderTest<N extends string> {
  name: N;
}

export type Tester<T> =
  T extends UnderTest<infer N>
    ? { name: `${N}`, passed: true }
    : { passed: false };

let x: Tester<Object>;
let y: Tester<UnderTest<"foo">>;

Which is doing what expected, that is, creating 2 variables of two different types, where the first type is { passed: false } and the second type is { name: "foo", passed: true }.

I would like to know whether it is possible to alter the "passed" case to include a property named after N. Basically, I would like for Tester<T> to do this.

export type Tester<T> =
  T extends UnderTest<infer N>
    ? { name: `${N}`, passed: true, `${N}`: "Yes, baby!" }
    : { passed: false };

So that y: Tester<UnderTest<"foo">> would have a foo: "Yes, baby!" property. As of Version 4.8.4, the declaration above triggers a few errors.

esri/views/shadergraph/v6.ts:59:41 - error TS1131: Property or signature expected.

59         ? { name: `${N}`, passed: true, `${N}`: "Yes, baby!" }
                                       ~~~

esri/views/shadergraph/v6.ts:59:47 - error TS1005: ';' expected.

59         ? { name: `${N}`, passed: true, `${N}`: "Yes, baby!" }
                                             ~

esri/views/shadergraph/v6.ts:59:62 - error TS1128: Declaration or statement expected.

59         ? { name: `${N}`, passed: true, `${N}`: "Yes, baby!" }
                                                            ~

esri/views/shadergraph/v6.ts:60:9 - error TS1128: Declaration or statement expected.

60         : { passed: false };
       ~

[12:35:38 PM] Found 4 errors. Watching for file changes.

CodePudding user response:

Intersect it with a mapped type:

? { name: `${N}`, passed: true } & { [_ in N]: "Yes, baby!" }

You might also have to add an infer constraint if this gives an error about N not being a property key:

T extends UnderTest<infer N extends string>

Since this mapped type only has one key and one value, we could also use Record to achieve the same thing:

? { name: `${N}`, passed: true } & Record<N, "Yes, baby!">
  • Related