[英]typescript can't resolve typing from graphql query that returns a union type
I would like to understand what is going on here, and since i'm not very experienced with typescript, any help would be greatly appreciated !我想了解这里发生了什么,并且由于我对 typescript 不是很有经验,因此将不胜感激任何帮助!
I've got a resolver to return one cost from database:我有一个解析器从数据库返回一个成本:
@Query(() => FixedOrVariableCost, { name: 'oneCost' })
async getOneCost(
@Args('id', { type: () => String }) id: MongooseSchema.Types.ObjectId
) {
return this.costsService.getOneCost(id);
}
Its return type FixedOrVariableCost is a union type:它的返回类型 FixedOrVariableCost 是一个联合类型:
const FixedOrVariableCost = createUnionType({
name: 'FixedOrVariableCost',
types: () => [FixedCost, VariableCost] as const,
});
Basically in my model, a cost is a fixed or a variable one.基本上在我的 model 中,成本是固定的或可变的。 Cost is an abstract interface in my graphql layer.
Cost 是我的 graphql 层中的一个抽象接口。
Generated schema:生成的架构:
union FixedOrVariableCost = FixedCost | VariableCost
oneCost(id: String!): FixedOrVariableCost!
Here is the query i'm using:这是我正在使用的查询:
const useGetOneCost = (id: string) =>
useQuery(['getOneCost', id], async () => {
return (
graphQLClient.request(
gql`
query GetOneCost($id: String!) {
oneCost(id: $id) {
... on Cost {
_id
kind
code
label
title
content
costType {
_id
code
label
}
costMargin {
_id
code
label
}
createdAt
createdBy {
_id
}
updatedAt
updatedBy {
_id
}
status {
_id
code
label
color
}
}
... on FixedCost {
fixedCostValue {
amount
currency {
_id
code
label
symbol
}
}
}
... on VariableCost {
variableCostValue
}
}
}
`,
{ id }
),
{
enabled: !!id,
}
);
});
The typing generated by graphql codegen is the following: graphql codegen 生成的类型如下:
export type GetOneCostQuery = {
__typename?: 'Query';
oneCost:
| {
__typename?: 'FixedCost';
_id: string;
kind: CostKind;
code: string;
label: string;
title?: string | null;
content?: string | null;
createdAt: any;
updatedAt: any;
costType: {
__typename?: 'CostType';
_id: string;
code: string;
label: string;
};
costMargin: {
__typename?: 'CostMargin';
_id: string;
code: string;
label: string;
};
createdBy: { __typename?: 'User'; _id: string };
updatedBy: { __typename?: 'User'; _id: string };
status: {
__typename?: 'GenericStatus';
_id: string;
code: string;
label: string;
color: string;
};
fixedCostValue: {
__typename?: 'FixedCostValue';
amount: number;
currency: {
__typename?: 'Currency';
_id: string;
code: string;
label: string;
symbol: string;
};
};
}
| {
__typename?: 'VariableCost';
_id: string;
kind: CostKind;
code: string;
label: string;
title?: string | null;
content?: string | null;
createdAt: any;
updatedAt: any;
variableCostValue: number;
costType: {
__typename?: 'CostType';
_id: string;
code: string;
label: string;
};
costMargin: {
__typename?: 'CostMargin';
_id: string;
code: string;
label: string;
};
createdBy: { __typename?: 'User'; _id: string };
updatedBy: { __typename?: 'User'; _id: string };
status: {
__typename?: 'GenericStatus';
_id: string;
code: string;
label: string;
color: string;
};
};
};
very nice !非常好 ! Typing generation works as expected
打字生成按预期工作
Now, one of my component receives a cost as a prop, so i'm picking oneCost
inside GetOneCostQuery
type现在,我的一个组件接收成本作为道具,所以我在
GetOneCostQuery
类型中选择oneCost
type PropType<TObj, TProp extends keyof TObj> = TObj[TProp];
type OneCost = PropType<GetOneCostQuery, 'oneCost'>;
type Props = {
cost: OneCost;
};
export const MyComponent = ({
cost
}: Props) => {
console.log(cost.fixedCostValue);
return null;
}
ts error on ``fixedCostValue: ``fixedCostValue 上的 ts 错误:
La propriété 'fixedCostValue' n'existe pas sur le type '{ __typename?: "FixedCost" | undefined; _id: string; kind: CostKind; code: string; label: string; title?: string | null | undefined; content?: string | null | undefined; createdAt: any; ... 6 more ...; fixedCostValue: { ...; }; } | { ...; }'.
La propriété 'fixedCostValue' n'existe pas sur le type '{ __typename?: "VariableCost" | undefined; _id: string; kind: CostKind; code: string; label: string; title?: string | null | undefined; content?: string | null | undefined; createdAt: any; ... 6 more ...; status: { ...; }; }'.ts(2339)
roughly in english: "Property 'fixedCostValue' doesn't exist on type blablabla"大致用英语:“blablabla 类型不存在属性‘fixedCostValue’”
Shouldn't this value maybe available, if cost is a fixed one?如果成本是固定的,这个值不应该是可用的吗? Why can't typescript recognize this value?
为什么 typescript 不能识别这个值? This confuses me...
这让我很困惑...
Thanks for your help谢谢你的帮助
Type OneCost
is a union, meaning it is one of two objects - either FixedCost
or VariableCost
.类型
OneCost
是一个联合,这意味着它是两个对象之一 - FixedCost
或VariableCost
。 While the first contains an attribute named fixedCostValue
, the second one doesn't, hence the error.虽然第一个包含一个名为
fixedCostValue
的属性,但第二个没有,因此出现错误。
If you'll check if this attribute exists in the object, it'll pass.如果您检查 object 中是否存在此属性,它将通过。 for example:
例如:
export const MyComponent = ({
cost
}: Props) => {
if ("fixedCostValue" in cost) {
console.log(cost.fixedCostValue);
};
return null;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.