TypeError: Object(...) не является функцией - функция возвращает глубокие копии объектов

У меня есть 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 еще не существовал?

Можете ли вы дать ссылку на codepen или игровую площадку TS или что-то, что показывает ошибку? Кроме того, как вы импортируете функцию buildUser?

Jared Smith 18.03.2022 16:49

@JaredSmith, я добавил импорт и редактирование внизу сообщения. Что касается детской площадки, я сделаю это, как только смогу.

Marco Castanho 18.03.2022 17:52
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
1
2
56
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Кажется, что порядок ваших констант неверен.

Переместите объявление 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) сделало это!

Marco Castanho 20.03.2022 18:45

А, я вижу - эти определения взяты из разных файлов. Это объясняет, почему function не помогло.

Lesiak 22.03.2022 14:28

Другие вопросы по теме