dsherret / ts-nameof

nameof in TypeScript
MIT License
492 stars 23 forks source link

Using ts-nameof with react-native-typescript-transformer #30

Closed wh1t3cAt1k closed 5 years ago

wh1t3cAt1k commented 6 years ago

I am wondering if it is possible to use ts-nameof in a React Native project that already uses react-native-typescript-transformer.

The setup section of the library prescribes using the TS transformation API with ttsc compilation.

My understanding is that it won't work seamlessly with RN TS transformer.

Could anyone advise other options?

dsherret commented 6 years ago

I'm going to take a guess here... no clue if this will work and probably won't, but could you try this out?

  1. Install ttypescript and ts-nameof:

    npm install --save-dev ttypescript ts-nameof
    // or
    yarn add --dev ttypescript ts-nameof
  2. Add ts-nameof to tsconfig.json as a custom transformer:

    {
        "compilerOptions": {
            "plugins": [{ "transform": "ts-nameof", "type": "raw" }]
        }
    }
  3. In rn-cli.config.js mentioned at https://github.com/ds300/react-native-typescript-transformer, add an import for "ttypescript".

    var ttypescript = require("ttypescript");

I believe importing ttypescript will currently cause the typescript module to be patched with ttypescript's modifications. If not, I'll open an issue at ttypescript to see if there's a way to patch an existing typescript version.


Also, doesn't look like there's a way to use a custom typescript version with RN TS transformer. It would probably be best if that allowed providing a custom version of the compiler.

Ideally, of course, it would be great if the typescript compiler just knew how to include these transformations itself... sorry for all the trouble!

wh1t3cAt1k commented 6 years ago

Hi David,

Hey, don't apologize for troubles that you didn't create! 😃

Unfortunately the approach didn't work:

image

For reference, here is my rn-cli.config.js:

var ttypescript = require("ttypescript");

module.exports = {
    getTransformModulePath() {
      return require.resolve("react-native-typescript-transformer");
    },
    getSourceExts() {
      return ["ts", "tsx"];
    }
};
wh1t3cAt1k commented 6 years ago

WORKAROUND:

I am currently using the following workaround:

// modules/nameof.ts
// -
export const nameof = (variableObject: any) => Object.keys(variableObject)[0];

But the downside is that I have to use the ES6 merged key-value syntax and redundantly pass objects around:

import { nameof } from 'modules/nameof`

const variable = 5;
const name = nameof({ variable });

Moreover, it is not possible to obtain the name of a nested property without destructuring:

import { nameof } from 'modules/nameof';

const foo = { bar: 5 };

// Won't work: 
// -
// const name = nameof({ foo.bar });

// I have to explicitly destructure:
// -
const { bar } = foo;
const name = nameof({ bar });

All in all, @dsherret I would be glad if we could get your package to work in react-native. Is there anything else I can help with?

dsherret commented 6 years ago

Sorry, I have completely neglected responding to this.

That's a pretty good idea for a workaround! For a property, you may want to do this:

function nameofProp<T>(obj: T, name: keyof T) {
    return name;
}

const myObj = { prop: "" };
const result = nameofProp(myObj, "prop");

The only way I can see this being fixed is if react-native-typescript-transformer is changed to allow passing in a custom version of the compiler. For example, ts-node allows specifying a different typescript compiler to use by specifying that as a command line option or environment variable (most likely an environment variable would by best for your situation).

wh1t3cAt1k commented 5 years ago

@dsherret hi David, is there any new hope with the 2.0 version?

dsherret commented 5 years ago

@wh1t3cAt1k no, still not possible. I've opened https://github.com/ds300/react-native-typescript-transformer/issues/88

By the way, it would be pretty easy to fork that project then inject ts-nameof on this line and provide the customTransformers option (ex. customTransformers: { before: [tsNameof] }).

wh1t3cAt1k commented 5 years ago

Hi David!

Thank you for opening that, let's see.

By the way, newer RN 0.57 uses babel-typescript out of the box, so typescript-transformer would not be needed.

Would integration perhaps be easier with babel?

On Fri, 30 Nov 2018, 01:33 David Sherret <notifications@github.com wrote:

@wh1t3cAt1k https://github.com/wh1t3cAt1k no, still not possible. I've opened ds300/react-native-typescript-transformer#88 https://github.com/ds300/react-native-typescript-transformer/issues/88

By the way, it would be pretty easy to fork that project then inject ts-nameof on this line https://github.com/ds300/react-native-typescript-transformer/blob/7aa16d351a14068b1dcfa95aa99edaa163686700/index.js#L210 and provide the customTransformers option (ex. customTransformers: { before: [tsNameof] }).

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/dsherret/ts-nameof/issues/30#issuecomment-443019067, or mute the thread https://github.com/notifications/unsubscribe-auth/AE667q489D_I8FRZ0CC1s-p6qZq0DPhIks5u0GDBgaJpZM4VHcgC .

dsherret commented 5 years ago

See my comment here about babel supporting typescript: https://github.com/dsherret/ts-nameof/issues/37#issuecomment-443548609

dsherret commented 5 years ago

Considering https://github.com/dsherret/ts-nameof/tree/master/packages/babel-plugin-ts-nameof now exists, I suggest using @babel/preset-typescript.