#Generic as interface key

54 messages · Page 1 of 1 (latest)

frigid lark
#

The interface APIResponse may accept a object type and a key. I want to infer this key in the interface as the object type provided.

TS Playground: Below

My english is kinda bad, so if you got any doubts just ask me

nocturne loomBOT
#
bluey#0012

Preview:```ts
export type APIResponseStatus = "error" | "success"

export interface APIResponse<
TResponse = any,
TResponseKey extends string = "response"

{
[K: TResponseKey]: TResponse
status: APIResponseStatus
code?: string | null
message?: string
}```

shadow kindle
#

!:index%

nocturne loomBOT
#
Gerrit0#7591
`!gerrit0:index-signatures`:

Index signatures apply to all members of the type that match the signature. Therefore, the following type is invalid, even though TypeScript does not detect it until you actually try to construct a value which conforms to the type.

type Foo = { a: 1 } & { [x: string]: 2 }

TypeScript does not have a way to specify "everything besides defined keys" since it does not have negated types. This pattern cannot be expressed in TypeScript today. A more TS-friendly version of it puts all of the extra properties on a dedicated key:

type Foo = { a: 1; extra: { [x: string]: 2 } }

negated types: https://github.com/microsoft/TypeScript/pull/29317

shadow kindle
#

but yeah also what the error says, consider using a mapped type instead

#

you'd want to separate it out though

#

you could have like, APIResponse<number, "status" | "code" | "message"> and now message should be both a number and a string, that doesn't make sense

#

having a separated object like in the example there would work, but honestly i feel like you may want to just reconsider the design in general

frigid lark
#

omg tysm

#

!resolved

frigid lark
frigid lark
shadow kindle
#

yes, because your type doesn't handle that well

shadow kindle
frigid lark
#

couldnt have neither cause it has a default value

shadow kindle
#

not how it works

frigid lark
#

actually, no problem having neither or both

shadow kindle
#

APIResponse<unknown, never> is perfectly valid for your type, never does extend string

shadow kindle
frigid lark
#

yes

shadow kindle
#

you do you then. that sounds like a terrible design ngl.

shadow kindle
#

"not gonna lie"

#

kinda like "tbh"/"to be honest"

frigid lark
frigid lark
shadow kindle
#

this is the opposite of simple

frigid lark
#

wdym?

shadow kindle
#

making it more specific would make it simpler, generics aren't meant for this kind of thing

#
// both are optional, meaning having neither or both are valid
type APIResponse<T = unknown> = {
  response?: T
  app?: T
  status: APIResponseStatus
  code?: string | null
  message?: string
};

// specified separately, would require `?: never` keys to ensure exclusivity but it works for literals
type APIResponse<T = unknown> = {
  status: APIResponseStatus
  code?: string | null
  message?: string
} & ({ response: T } | { app: T });
#

but just in general, having 2 possible result keys seems like code smell to me

frigid lark
#

not my fault

#

its just how this api works

shadow kindle
#

didn't you say it was for internal use

#

eh maybe i just misinterpreted what you meant there, whatever

frigid lark
shadow kindle
#

its just how this api works
yes im typing the api for personal use
so why not just... fix your api

frigid lark
#

ignore that

#

i mean

#

the api is public

#

im making the types

shadow kindle
#

ok

#

that clears that up

frigid lark
#

do generics affect performance?

shadow kindle
#

so back to this; just use the type that actually represents how the api works then. don't settle for "no problem"

shadow kindle
#

but generics affect readability and maintainability

frigid lark
shadow kindle
#

your usecase is far simpler than what generics are for, using generics obscures your intent and makes it harder to understand what you wrote

#

all this applies to yourself reading your own code in the future as well

frigid lark
#

btw i just talked to the api owner and they'll change it

#

yay

#

lmao