Is it possible to write an interface that accepts a string constant as one of its parameters, and uses that as the key of an object?
For instance, assuming I make two different GraphQL requests, both of which return a User
, but under different key names:
const userByIdResult = {
data: {
userById: {
id: 123,
username: 'joseph'
}
}
}
const userByUsernameResult = {
data: {
userByUsername: {
id: 123,
username: 'joseph'
}
}
}
I would imagine writing a generic interface would go something like this:
interface GraphQLResponse<QueryKey, ResponseType> {
data: {
[QueryKey]: ResponseType
}
}
interface User {
username: string
id: string
}
type UserByIdResponse = GraphQLResponse<'userById', User>
type UserByUsernameResponse = GraphQLResponse<'userByUsername', User>
But, this doesn't work.
Assigning Generic ParametersBy passing in the type with the <number> code, you are explicitly letting TypeScript know that you want the generic type parameter T of the identity function to be of type number . This will enforce the number type as the argument and the return value.
Using ?: with undefined as type definition While there are no errors with this interface definition, it is inferred the property value could undefined without explicitly defining the property type as undefined . In case the middleName property doesn't get a value, by default, its value will be undefined .
In TypeScript we can apply constraints on Generic type parameters (e.g. T) by using keyword extends (e.g. T extends Serializable).
Yes it is possible, but only for Functions, not any arbitrary variable. As you can see, it's the type itself, where you define generics and then you can make a variable of that type, which allows it to set the generic.
You're close. This falls under the category of Mapped Types. You need to make two changes:
QueryKey extends string
key in QueryKey
interface GraphQLResponse<QueryKey extends string, ResponseType> {
data: {
[key in QueryKey]: ResponseType;
}
}
interface User {
username: string;
id: number;
}
type UserByIdResponse = GraphQLResponse<'userById', User>;
type UserByUsernameResponse = GraphQLResponse<'userByUsername', User>;
Example Usage
const userByIdResult: UserByIdResponse = {
data: {
userById: {
id: 123,
username: 'joseph'
}
}
}
const userByUsernameResult: UserByUsernameResponse = {
data: {
userByUsername: {
id: 123,
username: 'joseph'
}
}
}
const userByIdResultBoom: UserByIdResponse = {
data: {
userByUsername: {
id: 123,
username: 'joseph'
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With