Home > OS >  Is there a way to construct tuple with extra properties without cast to any?
Is there a way to construct tuple with extra properties without cast to any?

Time:11-05

In order to support both array and object destructuring, I have the following Result type definition:

type Errors = Record<string, string | null>

type Result = [Errors, boolean] & { errors: Errors, success: boolean }

I have tried to construct such result in one statement, but could not find syntax that could do such a thing... Also, this other approach fails with error:

const result: Result = [errors, success]
result.errors = errors
result.success = success
return result

Type '[Errors, boolean]' is not assignable to type 'Result'.

Type '[Errors, boolean]' is not assignable to type '{ errors: Errors; success: boolean; }'

However, declaring result as any and applying type on the return works:

const result: any = [errors, success]
result.errors = errors
result.success = success
return result as Result

Is there better, type safe way to construct such object?

CodePudding user response:

Problems like this where you want an object to be both A and B at the same time but can't do an assignment in one line can often be solved with Object.assign(). This function allows combining two JavaScript objects at runtime and is also conveniently typed to intersect both object types.

The only problem in this case is the way that TypeScript types array literals. We need an assertion to tell TypeScript to type the passed array as a tuple.

const result: Result = Object.assign(
    { errors, success }, 
    [errors, success] as [Errors, boolean]
)

This reduces the type-safety as the type assertion allows us to forget an element in the tuple or to add some other element.

You could type Result to be an readonly array.

type Result = readonly [Errors, boolean] & { errors: Errors, success: boolean }

Then we could use as const.

const result: Result = Object.assign(
    { errors, success }, 
    [errors, success] as const
)

Which would give us 100% type-safety.


Playground

  • Related