问题
I am working with GraphQL and I want to have strict typing in gql
. Is it possible to make result
variable to be shape of ResultData
i.e. with the latest version of TypeScript. It is only about typing, not about runtime.
interface Data {
one: string;
two: number;
three: {
four: string;
five: {
six: Date;
};
};
}
// true means that this field must be added to query
type RecursivePartial<T> = {[P in keyof T]?: RecursivePartial<T[P]> | true};
function gql<T>(fields: RecursivePartial<T>) {
// Some code about generating GraphQL query
}
const result = gql<Data>({one: true, three: {five: {six: true}}});
// type ResultData {
// one: string;
// three: {
// five: {
// six: Date;
// };
// };
// }
回答1:
This is working for me in the playground:
interface Data {
one: string;
two: number;
three: {
four: string;
five: {
six: Date;
};
};
}
// Prevent widening of true to boolean in queries
type RecursivePartial1 = { [k: string]: RecursivePartial1 | true };
// true means that this field must be added to query
type RecursivePartial<T> = RecursivePartial1 & { [P in keyof T]?: RecursivePartial<T[P]> | boolean };
type RecursivePick<T, Q extends RecursivePartial<T>> =
{ [P in keyof T & keyof Q]:
Q[P] extends RecursivePartial<T[P]> ? RecursivePick<T[P], Q[P]> : T[P] };
function gql<T, Q extends RecursivePartial<T>>(data: T, fields: Q): RecursivePick<T, Q> {
// Some code about generating GraphQL query
}
declare const data: Data;
const result = gql(data, { one: true, three: { five: { six: true } } });
// type ResultData {
// one: string;
// three: {
// five: {
// six: Date;
// };
// };
// }
来源:https://stackoverflow.com/questions/51968157/type-gql-tag-in-typescript