1

I want to make my End-to-End testing easier and typesafer, by collecting and transforming the data-attributes in a typed constant object. However, I cannot make it work.

How can I create an union type out of an attribute value of multiple objects within an array?

interface Itest {
  name: string
  values: readonly string[]
}

const testAttributes: readonly Itest[] = [
  {
    name: "testid",
    values: [
      "playbarQueueIcon",
      "queueBar",
      "playbarPlayButton",
      "playbarPauseButton",
      "playbarPreviousButton",
      "playbarNextButton",
      // ...
    ] as const,
  } as const,
  {
    name: "testgroup",
    values: ["queueNextTracks", "queuePreviousTracks"] as const,
  } as const,
] as const

// ***********************
// Why does this not work?
// ***********************
type ITest = typeof testAttributes[number]["values"][number]


const attr = testAttributes.reduce((acc, {name, values}) => {
  for (const value of values) {
    acc[value] = `[data-${name}=${value}]`
  }

  return acc
}, {} as Record<ITest, string>
)

attr.queueBarXXXX // => Should not work
attr.queueBar // => Should work

1 Answer 1

1

Manually setting a type via : readonly Itest[] overrides what could be inferred. So values is string[] because that overrides the as const assertion. Remove that and you get the union I think you expect.

If you want testAttributes to satisfy the Itest[] type but be inferred to something more specific you need to wait for the satisfies operator to land in released typescript: https://github.com/microsoft/TypeScript/issues/47920

Or use a function:

function makeTestArray<T extends Itest[]>(arr: T): T { return arr }
const testAttributes = makeTestArray([...]) // data goes here.

Playground

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.