Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ts_transformer_keys_1.keys is not a function #4

Open
llanginger opened this issue Jun 22, 2017 · 50 comments
Open

ts_transformer_keys_1.keys is not a function #4

llanginger opened this issue Jun 22, 2017 · 50 comments

Comments

@llanginger
Copy link

llanginger commented Jun 22, 2017

Hi there!

This package sounds like the ideal solution to a problem I have but I am struggling to get past the following error: "TypeError: ts_transformer_keys_1.keys is not a function" and I am not sure how to tell if this is an error on my part or if there is something out of my control that is not working.

I have tried compiling the following file with typescript 2.4.0 and running in the browser with no other packages:

import { keys } from "ts-transformer-keys";

interface Props {
    id: string;
    name: string;
    age: number;
}
const keysOfProps = keys<Props>();

console.log(keysOfProps); 

I have also tried using ts-node and executing the same file from the command line, though here in particular I am unsure to what extend ts-node is a bottleneck.

I hope I'm missing something super simple!

Thanks in advance for any thoughts in any direction!

@llanginger
Copy link
Author

I think I misunderstood something fundamental about how one is meant to use this! Will reopen if after more thorough testing I still can't get anywhere!

@hhshan
Copy link

hhshan commented Aug 3, 2017

@llanginger were you able to come up with a workaround. cause I too ran into the same issue trying to use this package.

@kimamula
Copy link
Owner

kimamula commented Aug 3, 2017

The error TypeError: ts_transformer_keys_1.keys is not a function means that you have failed to get the custom transformer working during compilation.

Could you show me how you are using the custom transformer to compile your TypeScript codes?

@hhshan
Copy link

hhshan commented Aug 9, 2017

Hi @kimamula I got around the issue.. was a problem with how i used the transformer. thanks for the library.. helps to solve a major issue i was facing with

@martnst
Copy link

martnst commented Dec 27, 2017

I get the same TypeError: ts_transformer_keys_1.keys is not a function by simply adding it via yarn add -D ts-transformer-keys and then trying to use it as of the example. It seems there is some step missing in the docs?

@kimamula
Copy link
Owner

@martnst Sorry for the late response.
If you are using Windows, the issue is probably fixed by this commit.
Please try v0.3.1.

@pamls
Copy link

pamls commented Apr 20, 2018

@kimamula unfortunately, v0.3.1 does not work on Windows.

@martnst
Copy link

martnst commented Apr 23, 2018

FYI: I am on macOS

@kimamula
Copy link
Owner

kimamula commented Apr 23, 2018

@macbric @martnst I confirmed the following works both on macOS and Windows (with [email protected]).

  • index.ts
import { keys } from 'ts-transformer-keys';

interface Props {
  id: string;
  name: string;
  age: number;
}
const keysOfProps = keys<Props>();

console.log(keysOfProps);
  • compile.js
const ts = require('typescript');
const keysTransformer = require('ts-transformer-keys/transformer').default;

const program = ts.createProgram(['index.ts'], {
  strict: true,
  noEmitOnError: true,
  target: ts.ScriptTarget.ES5
});

const transformers = {
  before: [keysTransformer(program)],
  after: []
};
const { emitSkipped, diagnostics } = program.emit(undefined, undefined, undefined, false, transformers);

if (emitSkipped) {
  throw new Error(diagnostics.map(diagnostic => diagnostic.messageText).join('\n'));
}
  • compile and run
$ node compile # creates index.js
$ node index   # outputs "[ 'id', 'name', 'age' ]"

Could you provide your code so that I can investigate the problem?

@ludogithub
Copy link

ludogithub commented Aug 8, 2018

Hi,

For me the code :

import { keys } from 'ts-transformer-keys';

interface Props {
  id: string;
  name: string;
  age: number;
}
const keysOfProps = keys<Props>();

console.log(keysOfProps);

Gets compiled as :

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const ts_transformer_keys_1 = require("ts-transformer-keys");
const keysOfProps = ts_transformer_keys_1.keys();
console.log(keysOfProps);

And serves the error :

TypeError: ts_transformer_keys_1.keys is not a function

On windows, with typescript 2.9.2 and ts-transformer-keys 0.3.3.

Best,

Ludovic

@kimamula
Copy link
Owner

kimamula commented Aug 9, 2018

Hi,

I have listed several ways of how to use custom transformers in README.
Which way are you using?

@ghost
Copy link

ghost commented Sep 22, 2018

I see you added support for your plugin to awesome-typescript-loader. But unfortunately I switched to ts-loader some time ago because of performance problems: s-panferov/awesome-typescript-loader#570

Any chance of added support in ts-loader?

@kimamula
Copy link
Owner

@tentreescantbeatme Sorry for the late reply.
At that time, I also looked into ts-loader implementation and gave up to add support to it as it looked it is not easy to provide getCustomTransformers() with Program instance.

There is an issue on the ts-loader repository, so someone may working on it.
You can use ttypescript for the meantime.

@kimamula
Copy link
Owner

kimamula commented Jan 8, 2019

@tentreescantbeatme this issue was fixed and [email protected] can provide ts.Program to custom transformers, which enables ts-transformer-keys to work with ts-loader.

@Thanos-Pappas
Copy link

Thanos-Pappas commented Jan 28, 2019

Hello,
I'm getting the following error. TypeError: Object(...) is not a function on this line console.log( keys<MyInterface>()[0]);
I am using the following versions :

  • Angular: 7.2.0
  • typescript: 3.2.2
  • webpack: 4.28.4
  • awesome-typescript-loader: 5.2.0
  • @angular-builders/custom-webpack: 7.2.0
  • @angular-builders/dev-server: 7.2.1

A simplified version of my code:

my-inteface.ts

export interface MyInterface{
  keyA: string;
  keyB: string;
  keyC: string;
}

testTransformer.ts

import {keys} from 'ts-transformer-keys';
import {MyInterface} from '../../../interfaces/my-inteface';

export class TestTransformer{
  console.log( keys<MyInterface>()[0]);
}

I followed the webpack configuration as described here

My configurations follow:

angular.json

...
"architect": {
        "build": {
          "builder": "@angular-builders/custom-webpack:browser",
          "options": {
            "customWebpackConfig": {
              "path": "./extra-webpack.config.js"
            },
...

"serve": {
          "builder": "@angular-builders/dev-server:generic",
...

extra-webpack.config.js

const keysTransformer = require('ts-transformer-keys/transformer').default;
module.exports = {
  module: {
    rules: [
      {
        test: /\.ts$/,
        loader: 'awesome-typescript-loader',
        options: {
          getCustomTransformers: program => ({
  before: [
    keysTransformer(program)
            ]
          })
        }
      }
    ]}};

!! Also i'm getting a worning unused property getCustomTransformers
and I run the application with ng serve

Any ideas what is going wrong here?

@gabbifish
Copy link

gabbifish commented Mar 25, 2019

I am also using the same default webpack config as @Thanos-Pappas and am running into:

TypeError: ts_transformer_keys_1.keys is not a function

is there something missing from the webpack demo code? I am also running TS 3.2.2.

@zucker-rdrg
Copy link

zucker-rdrg commented Mar 28, 2019

I have same problem with jasmine-ts and ts-transformer-keys

EDIT: Instead of jasmine-ts I've just used jasmine with ts-node (to pass ts-node --compiler ttypescriptand it works fine :)

@kimamula
Copy link
Owner

kimamula commented Mar 30, 2019

@Thanos-Pappas I tested @angular-builders/custom-webpack with ts-transformer-keys and confirmed TypeError: Object(...) is not a function error.

I found several issues (such as this and this) suggesting that you have to use mergeStrategies: { "module": "prepend" } to apply additional TypeScript transformations with @angular-builders/custom-webpack.
However, using mergeStrategies: { "module": "prepend" } results in compilation errors such as the following:

ERROR in [at-loader] ./src/app/app.component.ts:8:5 
    TS2539: Cannot assign to 'AppComponent' because it is not a variable.

This even happens when I use awesome-typescript-loader (or ts-loader) without custom transformers, e.g., like the following:

module.exports = {
  module: {
    rules: [
      {
        test: /\.ts$/,
        loader: 'awesome-typescript-loader' // or 'ts-loader'
      }
    ]
  }
};

It is likely that

  1. TypeScript transformations executed before Angular transformers' transformation are ignored (mergeStrategies: { "module": "append" }, which is default)
  2. TypeScript transformations with awesome-typescript-loader or ts-loader are not possible after Angular transformers' transformation because the TS code is no longer compilable (mergeStrategies: { "module": "prepend" })

Note that webpack loaders are applied from the bottom to the top.

As of now, I cannot think of any good solution for this issue.

@gabbifish I haven't encountered TypeError: ts_transformer_keys_1.keys is not a function with @angular-builders/custom-webpack but this may be also related to you.

@YussufElarif
Copy link

I had the same problem i had to follow it using ttypescript.

  1. npm install --save-dev typescript ttypescript
  2. in package.json on "start": use ttsc instead of tsc
{
  "name": "api",
  "version": "0.0.0",
  "scripts": {
    "start": "ttsc && node ./dist/server",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "dependencies": {
    ...
  },
  "devDependencies": {
    ...
  }
  1. in tsconfig.json include plugin -> transform
{
  "compilerOptions": {
    ...
    "plugins": [
      { 
        "transform": "ts-transformer-keys/transformer"
      }
    ]
  },
  ...
}

I stopped getting the error after that 😅

@simllll
Copy link

simllll commented Jun 12, 2019

For me the issue was that I used the fork-ts-checker-webpack-plugin and therefore set transpileOnly: true. If transpileOnly is true, this plugin does not work. Makes kinda sense, took me still quite a while to figure it out ;).

TLDR: ensure transpileOnly is not set to true!

Regards
Simon

@ipetrovic11
Copy link

Hi @kimamula ,

Have you found the way to make this work with Angular or @ngtools/webpack?

The best I was able to do is to patch @ngtools/webpack so it uses ttypescript, but not sure that is sustainable model.

@pedrogscruz
Copy link

I had the same problem i had to follow it using ttypescript.

  1. npm install --save-dev typescript ttypescript
  2. in package.json on "start": use ttsc instead of tsc
{
  "name": "api",
  "version": "0.0.0",
  "scripts": {
    "start": "ttsc && node ./dist/server",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "dependencies": {
    ...
  },
  "devDependencies": {
    ...
  }
  1. in tsconfig.json include plugin -> transform
{
  "compilerOptions": {
    ...
    "plugins": [
      { 
        "transform": "ts-transformer-keys/transformer"
      }
    ]
  },
  ...
}

I stopped getting the error after that

I did exactly the same thing here and it still does not work.
My React App get the error TypeError: Object(...) is not a function.

@ryoikarashi
Copy link

I'm in the exact same scenario above.
Any solution or workaround on this issue?

@AmitSharmamad
Copy link

There is no such function as keys in the index.js file, kindly check that

@odykyi
Copy link

odykyi commented Nov 20, 2019

I have the same error TypeError: ts_transformer_keys_1.keys is not a function

I do not have webpack

I have only tsconfig.json and package.json

How can I fix this error?

@kimamula
Copy link
Owner

How are you transforming keys()?
As listed in README, there are typically 4 ways to transform keys().

@dungnguyen10989
Copy link

How are you transforming keys()?
As listed in README, there are typically 4 ways to transform keys().

I'm using TypeScript with React-Native, and error ts_transformer_keys_1.keys still appears, this is my devDendencies:

		"babel-jest": "^24.9.0",
		"babel-plugin-module-resolver": "^4.0.0",
		"eslint": "^6.5.1",
		"eslint-import-resolver-babel-module": "^5.1.2",
		"eslint-plugin-import": "^2.20.2",
		"eslint-plugin-module-resolver": "^0.16.0",
		"jest": "^24.9.0",
		"metro-react-native-babel-preset": "^0.58.0",
		"react-native-schemes-manager": "^2.0.0",
		"react-test-renderer": "16.11.0",
		"reactotron-react-native": "^5.0.0",
		"reactotron-redux": "^3.1.3",
		"reactotron-redux-saga": "^4.2.3",
		"ts-transformer-keys": "0.4.1",
		"tslint": "^6.1.2",
		"ttypescript": "^1.5.10",
		"typescript": "^3.8.3"

and tsconfig.json:

{
	"compilerOptions": {
		"allowJs": true,
		"allowSyntheticDefaultImports": true,
		"esModuleInterop": true,
		"isolatedModules": false,
		"jsx": "react",
		"lib": ["es6", "dom", "es2017"],
		"moduleResolution": "node",
		"noEmit": true,
		"strict": true,
		"target": "esnext",
		"baseUrl": ".",
		"paths": {
			"*": ["src"]
		},
		"plugins": [{ "transform": "ts-transformer-keys/transformer" }]
	},
	"exclude": [
		"node_modules",
		"babel.config.json",
		"metro.config.json",
		"jest.config.json"
	]
}

How can i fix it?

@ArashMotamedi
Copy link

In case this helps anybody else: I was planning to use ttsc but had mistakenly pasted the compilerOptions object into my package.json. The correct place is inside tsconfig.json file.

@dungnguyen10989
Copy link

In case this helps anybody else: I was planning to use ttsc but had mistakenly pasted the compilerOptions object into my package.json. The correct place is inside tsconfig.json file.

Can you show your tsconfig.json and package.json ? I've config like document, but this uncomfortable error still appears.

@maddalax
Copy link

maddalax commented May 15, 2020

I was able to get this working with Create React App by using https://github.com/timarney/react-app-rewired, https://www.npmjs.com/package/ttypescript, and https://www.npmjs.com/package/awesome-typescript-loader

config-overrides.js

module.exports = function override(config, env) {
    config.module.rules.push(  {
        test: /\.(ts|tsx)$/,
        loader: require.resolve('awesome-typescript-loader'),
        options: {
            compiler: 'ttypescript'
        }
    })
    return config;
}

tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": false,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "preserve",
    "plugins": [
      {
        "transform": "ts-transformer-keys/transformer"
      }
    ]
  },
  "include": [
    "src"
  ],
  "exclude": [
    "node_modules",
    "src/jestTrxProcessor.js",
    "src/test-*.js",
    "src/setupTests.js"
  ]
}

@kimamula
Copy link
Owner

kimamula commented Jun 2, 2020

@dungnguyen10989 If you are using Babel, it is not possible to get the transformer work. See #32.

@vmirage
Copy link

vmirage commented Jun 14, 2020

I have this issue as well with pnpm when while using ts-node --compiler ttypescript. No issues with ttsc. It seems that the issue here is the filepath mismatch due to symbolic link created by pnpm while using ts-node.

It can be fixed by changing

&& (path.join(declaration.getSourceFile().fileName) === indexTs)

to

import * as fs from 'fs';

...

 && (fs.realpathSync(path.join(declaration.getSourceFile().fileName)) === indexTs)

Not sure if this is the right way to fix it. But it works.

@kimamula
Copy link
Owner

@vmirage Thanks for reporting! I will look for if there is a better way to resolve this problem.

@kimamula
Copy link
Owner

@vmirage I found that using require.resolve() instead of path.join() works and published the fixed version (v0.4.2). Please give it a try. Thanks again for your report!

@vmirage
Copy link

vmirage commented Jun 18, 2020

@kimamula yup that works

@luisdemarchi
Copy link

@kimamula I arrived late, but unfortunately in the same bug. Using version 0.4.2

TypeError: ts_transformer_keys_1.keys is not a function

@kimamula
Copy link
Owner

kimamula commented Aug 5, 2020

@luisdemarchi please provide a reproduction. Thanks!

@benjamingwynn
Copy link

After testing this all day I think neither ts-transformer-keys or ts-interface-keys-transformer work with Webpack ts-loader when onlyCompiledBundledFiles is enabled. It appears as though the typechecker in the transformer code cannot determine the declaration from the symbol because the file is technically not imported as it's not one of the aforementioned "compiled bundle files" (typeChecker.getResolvedSignature(node).signature.declaration in isKeysCallExpression always reads undefined.)

This kind of makes sense, and I've disabled onlyCompiledBundledFiles for now, although that isn't ideal for my production build at all. Maybe somehow manually including the declaration file in the bundled files would fix it (I've tried using include on the webpack ts-loader module rule but to no avail, I'm still learning how to intelligently configure Webpack ). There are some mentions that .d.ts files will be automatically picked up, but the documentation is somewhat scarce (https://github.com/TypeStrong/ts-loader#onlycompilebundledfiles)

the following seem related: TypeStrong/ts-loader#1002, https://stackoverflow.com/a/52034546/3754229

@kimamula
Copy link
Owner

@benjamingwynn The doc of ts-loader says:

The onlyCompileBundledFiles option modifies this behavior, loading only those files that are actually bundled by webpack, as well as any .d.ts files included by the tsconfig.json settings.

And I confirmed that adding "files": ["node_modules/ts-transformer-keys/index.d.ts"], in tsconfig.json solves the problem. Please give it a try in your build.

@benjamingwynn
Copy link

benjamingwynn commented Aug 22, 2020

@kimamula thank you for getting back to me! this is correct and solved the issue at hand (...is not a function), but caused my specific case to return [] in place of the keys instead.

I am using node_modules with uncompiled Typescript modules as part of my development environment. If it helps anyone else, ts-loader with onlyCompileBundledFiles won't typecheck against anything in node_modules unless it is either: included in the include array in tsconfig.json as a file path (glob patterns seem to be ignored); or is a .d.ts file included in files. None of this will work unless allowTsInNodeModules is also true.

Edit: cleared up solution

@robbiemu
Copy link

robbiemu commented Feb 27, 2021

I'm on a mac. it seems like it is working for me with ttypecript (vsc hinting shows me that I have an array of union of valid properties), but in ts-jest I am getting this error. I believe my setup is equivalent to what is provided in the readme.. I have the same custom file and this in package.json (instead of jest.config):

  "jest": {
    "preset": "ts-jest",
    "testEnvironment": "node",
    "roots": [
      "<rootDir>/src"
    ],
    "moduleDirectories": [
      "node_modules",
      "src"
    ],
    "moduleNameMapper": {
      "@lib/(.*)": "<rootDir>/src/lib/$1"
    },
    "globals": {
      "ts-jest": {
        "astTransformers": { "before": ["./ts-jest-keys-transformer.js"] }
      }
    }

nvm, I realized that I just forgot to run jest --clearCache first .. it started working when I changed the factory to:

const factory = (cs) => (ctx) => {
  console.log(keysTransformer)
  return keysTransformer(cs.tsCompiler.program)(ctx)
};

@stevensnoeijen
Copy link

Got the same problem when running it in vscode with jest-runner, jest --clearCache fixed this problem :)

@alexlobera
Copy link

I had to update the factory function to make it work using "ts-jest": "^27.0.4"

// notice cs.program instead of cs.tsCompiler.program
const factory = cs => ctx => keysTransformer(cs.program)(ctx); // 👈 no `tsCompiler`

@ahmadalibaloch
Copy link

ahmadalibaloch commented Sep 18, 2021

Using nodejs with ts-node as ts-node ./src/server.ts and getting TypeError: (0 , ts_transformer_keys_1.keys) is not a function

code

import { keys } from 'ts-transformer-keys';

const nestKeys = keys<Nest>();

@crackedpotato007
Copy link

Was this fixed?
I am getting the same issue

@maranmaran
Copy link

Still ON

@keithort
Copy link

For anyone still struggling with this, another fun wrinkle I ran into was that the uses of keys that lived in __tests__ would throw this error. if I moved my tests into the root, then the function was found and executed.

@Ghostdog6
Copy link

We had been using this succesfully, but were having a similar problem when attempting to update our libraries (especially node). I'd updated my devDependencies to use "typescript": "^4.2.3". The server would build, but when trying to use the keys function we'd get an error saying "ts_transformer_keys_1 is not defined".

A coworker noticed that the devDependency on this package was ^3.9.5, so I did the same locally and it works again.

@behemoth-thainv
Copy link

I had the same problem i had to follow it using ttypescript.

  1. npm install --save-dev typescript ttypescript
  2. in package.json on "start": use ttsc instead of tsc
{
  "name": "api",
  "version": "0.0.0",
  "scripts": {
    "start": "ttsc && node ./dist/server",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "dependencies": {
    ...
  },
  "devDependencies": {
    ...
  }
  1. in tsconfig.json include plugin -> transform
{
  "compilerOptions": {
    ...
    "plugins": [
      { 
        "transform": "ts-transformer-keys/transformer"
      }
    ]
  },
  ...
}

I stopped getting the error after that 😅

It's work for me!

@nmgix
Copy link

nmgix commented Jan 25, 2024

nest.js + basic Jest testing
ts-jest + docs helped

jest.json

{
  "moduleFileExtensions": ["js", "json", "ts"],
  "rootDir": "../",
  "testEnvironment": "node",
  "testRegex": ".spec.ts$",
  "transform": {
    "^.+\\.(t|j)s$": "ts-jest"
  },
  "moduleNameMapper": {
    "^src/(.*)$": "<rootDir>/../src/$1"
  },
  "preset": "ts-jest",
  "globals": {
    "ts-jest": {
      "astTransformers": { "before": ["testing/helpers/ts-jest-keys-transformer.js"] }
    }
  }
}

and added ts-jest-keys-transformer.js in same folder

issue is that it warns ts-jest[ts-jest-transformer] (WARN) Define 'ts-jest' config under 'globals' is deprecated.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests