I'm having a TypeError: Object(...) is not a function
on the following scenario:
In order to initialize the state of a component with a given Article
(that will be fetched from the backend in componentDidMount
) I'm doing this
// ArticlePage.tsx
import { Article, buildArticle } from "../types";
// interfaces Props and State are properly defined above
export class ArticlePage extends Component<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
loading: true,
article: buildArticle(),
//...
}
}
}
In the types module, I define the type for Article
, a default article object to initialize state and a function to return deep copies of the default article object:
// types/Article.ts
import { buildUser, User } from ".";
export type Article = {
id: number;
user: User;
// ...
};
const articleSkeleton: Article = {
id: 0,
user: buildUser(), // <------ TypeError points to this line
//...
}
export const buildArticle = (): Article => _.cloneDeep(articleSkeleton); // _ is lodash
Same thing for User
// types/User.ts
export type User = {
id: number;
};
const userSkeleton: User = {
id: 0,
}
export const buildUser = (): User => _.cloneDeep(userSkeleton); // _ is lodash
Both of them under a types directory with an index.ts like this:
// types/index.ts
export * from "./Article";
export * from "./User";
If I define the articleSkeleton
object like this instead of using the buildUser
function
// types/Article.ts
const articleSkeleton: Article = {
id: 0,
user: _.cloneDeep(userSkeleton), // deep clone the object directly here instead of calling the buildUser() function to do it
//...
}
export const buildArticle = (): Article => _.cloneDeep(articleSkeleton); // _ is lodash
it works!
But in my head those are equivalent things...
Can someone explain me why they are not, why one works and the other doesn't?
Is what I am doing a bad practice and, if so, how should I handle this?
If I'm defining a type and a function to create objects of that type, would it be better to simply create a class instead?
What would be the pros and cons of that?
I've tried switching the order of the exports of Article
and User
in the index.ts
file and it works now...
// types/index.ts
export * from "./User";
export * from "./Article";
Could it be that, when it was running the buildUser()
function in Article
, the userSkeleton
object didn't exist yet?
It seems that the order of your constants is incorrect.
Move the declaration of buildUser()
before articleSkeleton
, or alternatively use a function
instead of a const
.
const buildUserOK = (): User => userSkeleton
const articleSkeleton = {
id: 0,
userError: buildUserError(),
userOk: buildUserOK(),
userOk1: buildUserFun(),
//...
}
type User = {
id: number;
};
const userSkeleton: User = {
id: 0,
}
const buildUserError = (): User => userSkeleton
function buildUserFun(): User {
return userSkeleton;
}