ts-transformer-keys icon indicating copy to clipboard operation
ts-transformer-keys copied to clipboard

ts_transformer_keys_1.keys is not a function

Open llanginger opened this issue 8 years ago • 50 comments

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 avatar Jun 22 '17 00:06 llanginger

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!

llanginger avatar Jun 22 '17 07:06 llanginger

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

hhshan avatar Aug 03 '17 09:08 hhshan

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?

kimamula avatar Aug 03 '17 18:08 kimamula

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

hhshan avatar Aug 09 '17 04:08 hhshan

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?

martnst avatar Dec 27 '17 12:12 martnst

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

kimamula avatar Feb 12 '18 15:02 kimamula

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

pamls avatar Apr 20 '18 19:04 pamls

FYI: I am on macOS

martnst avatar Apr 23 '18 09:04 martnst

@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?

kimamula avatar Apr 23 '18 16:04 kimamula

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

ludogithub avatar Aug 08 '18 07:08 ludogithub

Hi,

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

kimamula avatar Aug 09 '18 01:08 kimamula

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: https://github.com/s-panferov/awesome-typescript-loader/issues/570

Any chance of added support in ts-loader?

ghost avatar Sep 22 '18 23:09 ghost

@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 avatar Dec 17 '18 14:12 kimamula

@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.

kimamula avatar Jan 08 '19 12:01 kimamula

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?

Thanos-Pappas avatar Jan 28 '19 16:01 Thanos-Pappas

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.

gabbifish avatar Mar 25 '19 05:03 gabbifish

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 :)

zucker-rdrg avatar Mar 28 '19 11:03 zucker-rdrg

@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.

kimamula avatar Mar 30 '19 07:03 kimamula

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 😅

YussufElarif avatar Apr 09 '19 14:04 YussufElarif

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

simllll avatar Jun 12 '19 09:06 simllll

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.

ipetrovic11 avatar Jun 30 '19 18:06 ipetrovic11

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.

pedrogscruz avatar Jul 04 '19 18:07 pedrogscruz

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

ryoikarashi avatar Aug 04 '19 15:08 ryoikarashi

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

AmitSharmamad avatar Oct 05 '19 22:10 AmitSharmamad

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?

odykyi avatar Nov 20 '19 12:11 odykyi

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

kimamula avatar Nov 20 '19 15:11 kimamula

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?

dungnguyen10989 avatar May 10 '20 12:05 dungnguyen10989

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.

ArashMotamedi avatar May 11 '20 20:05 ArashMotamedi

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.

dungnguyen10989 avatar May 14 '20 13:05 dungnguyen10989

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"
  ]
}

maddalax avatar May 15 '20 15:05 maddalax