Home > Net >  Typesript typing an array of objects of unknown shape
Typesript typing an array of objects of unknown shape

Time:10-31

I am trying to construct a type for row in table. All I know is that keys must be string, and key values must be string or number or boolean. I have this:

type Row = Record<string, number | string | boolean>;

interface User {
    name: string
}

const objArr: User[] = [
    {name: 'John'},
    {name: 'Jack'}
]

const testArr: Row[] = objArr 

But there is an error:

Type 'User[]' is not assignable to type 'Row[]'.
  Type 'User' is not assignable to type 'Row'.
    Index signature for type 'string' is missing in type 'User'.(2322)

I am not sure how to construct a type for object of unknown shape...

CodePudding user response:

It would be better for you to completely know what sort of data you're dealing with, otherwise you lose the benefits of having TypeScript altogether.

With that said, you could do something like the following:

interface User {
  name: string
}

type Row = User & Record<string, number | string | boolean>;

const objArr: Row[] = [
    {name: 'John'},
    {name: 'Jack'}
]

const testArr: Row[] = objArr 

const someVar= testArr[0]["something"]
// type of someVar: number | string | boolean

What you have here is type extension, where Row contains User data, as well as other possible entries.

Drawback

If you go down this route however, it may be wise to also use Partial with the Record keyword, as you cannot guarantee that any given key will exist... (or have a value)

interface User {
  name: string
}

type Row = User & Partial<Record<string, number | string | boolean>>;

const objArr: Row[] = [
    {name: 'John'},
    {name: 'Jack'}
]

const testArr: Row[] = objArr 

const someVar= testArr[0]["something"]
// type of someVar: number | string | boolean | undefined

CodePudding user response:

Consider using an assertion here:

type Row = Record<string, number | string | boolean>;

interface User {
    name: string
}

const objArr: User[] = [
    {name: 'John'},
    {name: 'Jack'}
]

const testArr = objArr as Row[]

TypeScript dislikes this assignment since Row has an index signature while User doesn't. This would mean that you could use any key with Row, but not with User, hence the error.

  • Related