Hookyns / tst-reflect

Advanced TypeScript runtime reflection system
MIT License
338 stars 11 forks source link

[BUG] tst-reflect: You call getType() method directly. You have probably wrong configuration, because tst-reflect-transformer package should replace this call by the Type instance. #75

Closed Manik-Jain closed 2 years ago

Manik-Jain commented 2 years ago

Describe the bug

I have been using this library with NestJS and Typescript, with essentially the same configurations mentioned in readme, to instantiate my objects at runtime.

Observation: The code executes like 1/5 runs, and fails otherwise with the error : tst-reflect: You call getType() method directly. You have probably wrong configuration, because tst-reflect-transformer package should replace this call by the Type instance.

The code causing the problem


Mapper.map(newObject, getType<MyType>()) as MyType

To Reproduce Steps to reproduce the behavior:

  1. npx ttsc
  2. npm start to run my NestJS

Expected behavior Code shall execute successfully each time without any issues

Runtime (please complete the following information):

Additional context Add any other context about the problem here.

Hookyns commented 2 years ago

Hi @Manik-Jain, I'm expecting that your npm start invokes nest start.

The problem is that nest start executes build too (maybe not always; maybe only when there are some changes; probably it builds always but incremental build is enabled so it does not rebuild when there are no changes). But when the build is initiated by nest, it does not call ttsc it calls just tsc; or webpack in case of monorepo.

So in that case it will not use the tst-reflect-transformer. So I looked up this issue https://github.com/nestjs/nest-cli/issues/1208. And the answer:

If you want to use a different compiler, simply use it directly (without relying on nest build)

is quite... pointless... since nest start executes the build too.

So I was looking for some options to disable that building by nest start or some else configuration and I found this issue https://github.com/nestjs/nest-cli/issues/725

If you don't need to compile the code, run node dist/main.

So you have to use build: npx ttsc, start: node dist/main and there should be no problem.

Or second option is to use ts-patch, which will override typescript package so the "native" tsc cmd will invoke compilation with transformer, every time. So you can use nest build and nest start cmds.

Hookyns commented 2 years ago

@Manik-Jain Closing for now, it helped I suppose. Let me know if it doesn't.

Hookyns commented 2 years ago

Related https://github.com/Hookyns/tst-reflect/issues/37

Manik-Jain commented 2 years ago

Hi @Hookyns thanks for suggesting the work around, it worked for me. However, I'm running into issues with jest tests. Is there something that you can suggest?

Hookyns commented 2 years ago

Your tests? What kind of issues?

BTW Jest is configured in this repo and it works just fine.

Manik-Jain commented 2 years ago

I'm running the tests with ttsc -p tsconfig.json && jest with following jest configuration:

"jest": {
    "moduleFileExtensions": [
      "js",
      "json",
      "ts"
    ],
    "rootDir": "src",
    "testRegex": ".*\\.spec\\.ts$",
    "transform": {
      "^.+\\.(t|j)s$": "ts-jest"
    },
    "collectCoverageFrom": [
      "**/*.(t|j)s"
    ],
    "coverageDirectory": "../coverage",
    "testEnvironment": "node"
  }

tsconfig.json

{
  "compilerOptions": {
    "module": "commonjs",
    "declaration": true,
    "removeComments": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "allowSyntheticDefaultImports": true,
    "target": "es2017",
    "sourceMap": true,
    "outDir": "./dist",
    "baseUrl": "./",
    "incremental": true,
    "skipLibCheck": true,
    "strictNullChecks": false,
    "noImplicitAny": false,
    "strictBindCallApply": false,
    "forceConsistentCasingInFileNames": false,
    "noFallthroughCasesInSwitch": false,
    "useDefineForClassFields": true,
    "allowJs": true,
    "plugins": [
      {
          "transform": "tst-reflect-transformer"
      }
  ]
  },
  "ts-node": {
    "compiler": "ttypescript"
},
}

And getting the following error for each line of code that uses tst-reflect

[ERR] tst-reflect: You call getType() method directly. You have probably wrong configuration, because tst-reflect-transformer package should replace this call by the Type instance.
      If you have right configuration it may be BUG so try to create an issue.
      If it is not an issue and you don't want to see this debug message, create field 'tst-reflect-disable' in global object (window | global | globalThis) 
Hookyns commented 2 years ago

Your Jest configuration use TS files from src directory. You have to use your JS files from dist directory.

DSoko2 commented 1 year ago

I had a similar issue. I run my tests from the *.ts files with ts-jest. Looking at your information above @Manik-Jain there is two more things I had to do (using the current alpha releases or rttist and tst-reflect*):

  1. Configure ts-jest to use ttypescript (instead of standard typescript), such that it uses the transformer configured in tsconfig.json. It can be configure like described here https://github.com/cevek/ttypescript#jest-ts-jest which is the outdated ts-jest config format, the new one would be replacing your transform config above "transform": {"^.+\\.(t|j)s$": "ts-jest"} with "transform": {"^.+\\.(t|j)s$": ["ts-jest", { "compiler": "ttypescript" }]}.

  2. Make sure rttist's metadata is available. My project is configured with rootDir ./src and outDir ./bin in tsconfig. I am not sure why, but my tests look in src for the metadata causing them to fail. If I build normally with ttsc and run the built project with node, everything is fine, i.e., the metadata is correctly looked up from bin. I could fix the issue by setting rttist metadata.metadataTypelibPath option to ../bin/metadata.typelib.js (default: metadata.typelib.js). To do so, I replaced my transformer config in ts config with the snippet below. This makes my testing setup work and does not break the built application. Note, to have the metadata available, I have to build the project with ttsc before running jest.

{
    "transform": "tst-reflect-transformer",
    "reflection": {
        "metadata": {
            "metadataTypelibPath": "../bin/metadata.typelib.js"
        }
    }
}