«Не удается прочитать свойство» при использовании deferConfig конфигурации узла в «TypeScript

#node.js #typescript #node-config

Вопрос:

Я использую node-config в TypeScript.
У меня есть код, как показано ниже:
config/default.ts :

 import {deferConfig} from 'config/defer';
export default {
  service: {
    url: 'http://localhost',
    errorUrl: deferConfig(function() {
      console.info('config before defer:', this);
      return `${this['service']['url']}/error.html`;
    }),
  },
};

 

src/demo.ts :

 import config from 'config';
console.info('resulting config: ', config)
 

Это отлично работает, когда я запускаю свой код ts-node .

 $ npx ts-node ./src/demo.ts
config before defer: { service: { url: 'http://localhost', errorUrl: [Getter] } }
resulting config:  Config {
  service: { url: 'http://localhost', errorUrl: 'http://localhost/error.html' }
}
 

Тем не менее, если я запускаю код , скомпилированный с tsc , я получаю

 $ NODE_CONFIG_DIR=./build/config ./build/src/demo.js
config before defer: {
  default: { service: { url: 'http://localhost', errorUrl: [Getter] } }
}
.../build/config/default.js:9
            return `${this['service']['url']}/error.html`;
                                     ^
TypeError: Cannot read property 'url' of undefined
 

Значение this имеет дополнительный уровень default .
Почему такое поведение несовместимо для кода ts и js?
Если я изменю export default на export = , это будет работать как для кода ts, так и для кода js.
Тем не менее, документ node-config просит меня использовать export default .
Должен ли я использовать export = вместо этого?

Комментарии:

1. откуда вы сделали распечатку this ?

2. @tromgy я напечатал this внутри функции отсрочки. Я обновил вопрос. Надеюсь, это понятнее. 🙂

3. Расхождение между tsc и ts-узлом может быть связано с «экспериментальной» поддержкой модулей ESM в ts-узле: github.com/TypeStrong/ts-node/issues/1007 . Но также анонимный экспорт по умолчанию считается плохой практикой: github.com/import-js/eslint-plugin-import/blob/v2.24.2/docs/… Так что вы также можете попробовать что-то вроде const my_config = { /* the object you want to export */ }; export default my_config; Еще, я нахожу очень странным, что вы получаете реальный объект с именем «по умолчанию» в качестве своего this .

4. @tromgy Использование именованного экспорта по умолчанию, похоже, не меняет результат. Но спасибо вам за то, что указали на наилучшую практику.