#How would I type an array of an interface with a generic?

1 messages · Page 1 of 1 (latest)

elder sierra
#

The title is a bit confusing, I don't know how to explain what I want, but I have an example:


interface Routes {
  '1': { data: string },
  '2': { data: string },
  '3': { data: string },
}

type RouteName = keyof Routes;
type RouteParameters<T extends RouteName> = Record<keyof Routes[T], any> & Record<string, any>;

interface RouteLink<T extends RouteName> {
  name: T
  parameters?: RouteParameters<T>
}

// How would I type this
const links: RouteLink[] = [ // err: Generic type 'RouteLink<T>' requires 1 type argument(s).ts(2314)
  {
    name: '1', // where I can infer T here
  }
]```
livid seal
#

for declarations, there's no inference if you just specify it
you probably want something like this

const links = [
  // ...
] as const satisifies RouteLink<RouteName>[];
#

btw, RouteLink isn't exactly safe, since T could be a union.

#

actually no too sure about that being an issue, but something to look out for i guess

elder sierra
#

I like the idea, but it doesn't seem to function

#
  The type 'readonly [{ readonly name: "1"; }]' is 'readonly' and cannot be assigned to the mutable type 'RouteLink<keyof Routes>[]'.ts(1360)```
#

it seems really dumb, but I tried this, and it seems to function just fine, just wish there was a ts way to do this instad of a function that does nothing but echo the data I give it for type safety

interface Routes {
  '1': { data1: string },
  '2': { data2: string },
  '3': { data3: string },
}

type RouteName = keyof Routes;
type RouteParameters<T extends RouteName> = Record<keyof Routes[T], any> & Record<string, any>;

interface RouteLink<T extends RouteName> {
  name: T
  parameters?: RouteParameters<T>
}

const route = <T extends RouteName>(data: { name: T, parameters?: RouteParameters<T> }) => data as RouteLink<T>;

// How would I type this
const links = [
  route({ name: '1', parameters: {data1: 'test'}}),
  route({ name: '2', parameters: {data2: 'test'}}),
] as const;

if any one else has a suggestion lmk

livid seal
#

missed a readonly there, mb

#

you could also remove the as const i think?

#

was on mobile last time so couldn't check

sudden topazBOT
#
that_guy977#0

Preview:```ts
interface Routes {
'1': { data1: string },
'2': { data2: string },
'3': { data3: string },
}

type RouteName = keyof Routes;
type RouteParameters<T extends RouteName> = Record<keyof Routes[T], any> & Record<string, any>;

interface RouteLink<T extends RouteName> {
...```

elder sierra
#

it doesn't throw, but it isn't type safe unfortunately

const links = [
  { name: '1', parameters: {data3: 'test'}}, // should throw 
  { name: '2', parameters: {data2: 'test'}},
] satisfies RouteLink<RouteName>[];```
#

vs

const links = [
  route({ name: '1', parameters: {data3: 'test'}}), //will throw
  route({ name: '2', parameters: {data2: 'test'}}),
] as const;
#

Really appreciate the help BTW 🙏

livid seal
#

honestly kinda shrugging right now, sorry

#

getting kinda late