一些上下文:使用graphql我有用于自动生成查询的预定义接口,但是任何给定查询的结果只是该自动生成接口的子集
并且要对查询结果接口进行编译时检查,我需要一个接口,该接口是超级接口的自定义子集(严格没有任何其他参数),
一个例子...
type RecursivePartial<T> = {
[P in keyof T]?: RecursivePartial<T[P]>;
};
interface IAutogenerated {
name : string
weight: number
age: number
}
interface ICustom extends RecursivePartial<IAutogenerated> {
name: string
agez : number // <------ I want this not allowed at compiletime ( ie: because it's a typo!)
}
let a : ICustom = {
name : "me" // this is required, weight is not because the usage of "RecursivePartial"
}
在此示例中,我希望ICustom完全是IAutoGenerated的子集(也许具有一些创造性的“ keyof”用法?
在Java中,我将在扩展接口的每个成员中使用重写,以确保不添加错字并在重构期间让编译器帮助我。.
打字稿的版本:3.3
谢谢你, 弗朗切斯科
编辑: 给定汤姆的答案,我添加了另一个示例,它可能进一步揭示RecursivePartial的实际用法
// ------ AUTOGENERATED INTERFACE OF GRAPHQL -----
export interface People {
id: number;
name: string;
gender: Gender;
age: number;
childs: (Maybe<People>)[];
}
/// CUSTOMIZATION BASED ON SINGLE CREATED QUERY
export type Child = Pick<RecursivePartial<People>,
'name'
>
export type PeopleListItem = Pick<RecursivePartial<People>,
'id'|'name'|'childs' >
// what is needed here something between the Pick ( which allow strict subset ) and RecursivePartial, which allow super-typing of subset elements )
// export interface PeopleListItem extends RecursivePartial<People>{
// id : number,
// name : string,
// childs : Child[] // NOTE --> here Child is a subtype of People
// }
为了提供一些上下文,这将构成gql的返回类型:
query {
people {
id
name
childs {
name
}
}
此处带有注释的代码,我没有Pick的子类型严格性, 但是我可以使用Pick来用“ Partial”来代替成员,我不能覆盖元素,但是我有严格的子类型..
似乎有一个怪异的问题,但是这些约束都必须具有类型化的对象子图
编辑2: 我创建了一个提供一些要求的怪物,但是它非常丑陋,自1周以来我一直在使用打字稿,所以请原谅以下代码。(并请帮助我找到更好的东西)
type RecursivePartial<T> = {
[P in keyof T]?: RecursivePartial<T[P]>;
};
type RecursivePartialPick<T, K extends keyof T> = {
[P in K]: RecursivePartial<T[P]>;
};
// ------ AUTOGENERATED INTERFACE OF GRAPHQL -----
export interface People {
id: number;
name: string;
gender: Gender;
age: number;
childs: (Maybe<People>)[];
}
/// CUSTOMIZATION BASED ON SINGLE CREATED QUERY
export type Child = RecursivePartialPick<People, 'name' >
// this will stabilize sub-fields Picke'd from the original type (Avoid typing errors and code duplication )
type _PeoplePick = 'id' | 'name' | 'childs';
// override the field with a subtype
interface _PeopleListItem extends RecursivePartialPick<People,_PeoplePick >{
childs : Child[] //<<--- note here : no safety against typing errors in "childs" field name ( Except that resulting type is not Child[] but (Maybe<People>)[];
}
export type PeopleListItem = Pick<_PeopleListItem,_PeoplePick>
let result : PeopleListItem = {
name : "" ,
id : 2 ,
childs : [{ // <Child[]>
name : "n"
}]
}
答案 0 :(得分:1)
type Custom = Pick<RecursivePartial<IAutogenerated>, 'name' | 'age'>; // OK
type Custom2 = Pick<RecursivePartial<IAutogenerated>, 'name' | 'agez'>; // Type error