У меня есть TypeError: Object(...) is not a function
по следующему сценарию:
Чтобы инициализировать состояние компонента с заданным Article
(который будет получен из бэкэнда в componentDidMount
), я делаю это
// 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(),
//...
}
}
}
В модуле типов я определяю тип для Article
, объект статьи по умолчанию для инициализации состояния и функцию для возврата глубоких копий объекта статьи по умолчанию:
// 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
То же самое для пользователя
// types/User.ts
export type User = {
id: number;
};
const userSkeleton: User = {
id: 0,
}
export const buildUser = (): User => _.cloneDeep(userSkeleton); // _ is lodash
Оба они находятся в каталоге типов с index.ts следующим образом:
// types/index.ts
export * from "./Article";
export * from "./User";
Если я определяю объект articleSkeleton
таким образом вместо использования функции buildUser
// 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
оно работает!
Но в моей голове это равнозначные вещи...
Может кто-нибудь объяснить мне, почему их нет, почему один работает, а другой нет?
Является ли то, что я делаю, плохой практикой, и если да, то как мне с этим справиться?
Если я определяю тип и функцию для создания объектов этого типа, не лучше ли вместо этого просто создать класс?
Каковы будут плюсы и минусы этого?
Я попытался изменить порядок экспорта Article
и User
в файле index.ts
, и теперь это работает...
// types/index.ts
export * from "./User";
export * from "./Article";
Может ли быть так, что когда он запускал функцию buildUser()
в Article
, объект userSkeleton
еще не существовал?
@JaredSmith, я добавил импорт и редактирование внизу сообщения. Что касается детской площадки, я сделаю это, как только смогу.
Кажется, что порядок ваших констант неверен.
Переместите объявление buildUser()
перед articleSkeleton
или, альтернативно, используйте function
вместо 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;
}
Спасибо. Использование function
вместо const
ничего не изменило, но объявление buildUser()
перед articleSkeleton
(в моем редактировании я объясняю, что я изменил порядок экспорта в index.ts
) сделало это!
А, я вижу - эти определения взяты из разных файлов. Это объясняет, почему function
не помогло.
Можете ли вы дать ссылку на codepen или игровую площадку TS или что-то, что показывает ошибку? Кроме того, как вы импортируете функцию
buildUser
?