I have an error message from VSCode when using the "foreign key" property for storing an object. I've implemented the exact example from their documentation: https://docs.amplify.aws/lib/datastore/relational/q/platform/js/#updated-schema
It's 2 entities: Post and Comment with a bidirectional relationship:
- Post ---@hasMany---> Comment
- Post <--@belongsTo-- Comment
Here is the code copy/pasted from the docs into schema.graphql:
input AMPLIFY { globalAuthRule: AuthRule = { allow: public } } # FOR TESTING ONLY!
enum PostStatus {
ACTIVE
INACTIVE
}
type Post @model {
id: ID!
title: String!
rating: Int!
status: PostStatus!
# New field with @hasMany
comments: [Comment] @hasMany(indexName: "byPost", fields: ["id"])
}
# New model
type Comment @model {
id: ID!
postID: ID! @index(name: "byPost", sortKeyFields: ["content"])
post: Post! @belongsTo(fields: ["postID"])
content: String!
}
My .ts file with the content of the function copy/pasted from their documentation:
import { DataStore } from "aws-amplify"
import { Post, Comment, PostStatus } from "./models/index"
async function createPost() {
const post = await DataStore.save(
new Post({
title: "My Post with comments",
rating: 10,
status: PostStatus.ACTIVE
})
);
await DataStore.save(
new Comment({
content: "Loving Amplify DataStore!",
postID: post.id // <<<<<<<<<<<< Compile error
})
);
}
On the postID proprety, VSCode complains with the followind error.
Argument of type '{ content: string; postID: string; }' is not assignable to parameter of type 'ModelInit<Comment, CommentMetaData>'.
Object literal may only specify known properties, but 'postID' does not exist in type 'ModelInit<Comment, CommentMetaData>'. Did you mean to write 'post'?ts(2345)
Indeed, Comment.postID is not defined in the src/models/index.d.ts file generated by Amplify codegen model.
Comment.post exists, but not Comment.postID.
export declare class Post {
readonly id: string;
readonly title: string;
readonly rating: number;
readonly status: PostStatus | keyof typeof PostStatus;
readonly comments?: (Comment | null)[];
readonly createdAt?: string;
readonly updatedAt?: string;
constructor(init: ModelInit<Post, PostMetaData>);
static copyOf(source: Post, mutator: (draft: MutableModel<Post, PostMetaData>) => MutableModel<Post, PostMetaData> | void): Post;
}
export declare class Comment {
readonly id: string;
readonly post: Post;
readonly content: string;
readonly createdAt?: string;
readonly updatedAt?: string;
constructor(init: ModelInit<Comment, CommentMetaData>);
static copyOf(source: Comment, mutator: (draft: MutableModel<Comment, CommentMetaData>) => MutableModel<Comment, CommentMetaData> | void): Comment;
}
VSCode does not complain anymore if I rename my file using the DataStore as a .js instead of a .ts.
If add the Comment.postId attribute manually in the generated index.d.ts
export declare class Comment {
readonly id: string;
readonly post: Post;
readonly postID: string;
then the error disappears but another one comes:
Argument of type '{ content: string; postID: string; }' is not assignable to parameter of type 'ModelInit<Comment, CommentMetaData>'.
Property 'post' is missing in type '{ content: string; postID: string; }' but required in type 'ModelInit<Comment, CommentMetaData>'.ts(2345)
Indeed: Comment.post has not been assigned (as if I'm supposed to query for the Post in order to assign it to Comment.post instead of just assigning Comment.postId with the id of the comment, which would not be nice).
I'm new to Typescript and Amplify. Any idea what I am doing wrong ? Or is it a documentation mistake ? Or a bug in codgen ?
Thank you.