react-native-typescript-transformer icon indicating copy to clipboard operation
react-native-typescript-transformer copied to clipboard

Got RN-Web platform-specific file extensions working manually, how could we automate this?

Open mosesoak opened this issue 6 years ago • 7 comments

Hi, thanks for this excellent project, makes setting up RN + TS a lot easier!

I've integrated this with React Native Web which supports file splitting by extension (.web.tsx / .native.tsx / .ios.tsx / .android.tsx). However, Typescript doesn't play nicely with that piece of magic.

I opened a similar issue at the RNW repo asking if anyone has the know-how to write a piece of magic that would get this under the hood? Or is this something that's already supportable?

Demo of my (hacky) system: https://github.com/mosesoak/react-native-web-ts-app

mosesoak avatar Feb 06 '18 01:02 mosesoak

^ made the repo public 😬

mosesoak avatar Feb 06 '18 06:02 mosesoak

My brain broke on this problem as well. The packager(s) are pacified, but TS isn't.

Thankfully, I was only writing a proof-of-concept prototype, but here's how I got around this.

Introducing...

Sadly-Typed Components

Say you're building the <Multi /> component.

Make it a directory that has it's contents look like this:

image

index.ts looks like this:

export * from './multi'

But you see how there's no .web.tsx? That's because the web version is .tsx. In fact, you want to not have .native.tsx as long as you can hold out.

For example: here's what most components should strive to look like:

image

Using Sadly-Typed Components

And here's how you use those components:

import { Multi } from "../some/path/to/multi"

Why These Are Sadly-Typed

It forces you to have the same public interface between both platforms. I ran into TS problems as soon I started doing things like: "ohai native component! you get an extra prop!".

TS is unlikely to get a solution to this as conditional imports goes against their whole #static-4-lyfe design.

This whole approach is wrong and you will burn in hell if you do it.

But, if nobody is watching you... this works well.

If you find the right way™, please let me know. I will email you a beer.

skellock avatar Feb 06 '18 11:02 skellock

@skellock cool, thanks for sharing your system! Mine does indeed let you use platform specific extensions, like .web.tsx / .native.tsx. Check out my example repo!

What I'm struggling to figure out is how we could get TS to support this magic, possibly via an npm module. The problem is that prior to compiling to a platform, even if TS was aware of the special imports it still has no idea which path to follow to do its type checking. In reality it would be a union type of all of the various files' contents.

Perhaps I should start discussing this with the TS authors, was hoping to find someone who would know how to write this as a 3rd-party extension.

mosesoak avatar Feb 06 '18 17:02 mosesoak

Sadly-Typed Components

:joy:

Not sure how to automate this. I think it would require a new TypeScript module resolution strategy which extends node. I imagine the MS folks would be OK with including something like that, they've made plenty of concessions for the React ecosystem already.

ds300 avatar Feb 07 '18 15:02 ds300

Cool. I've been able to simplify the system to just use index files without the weird shim file, retry the repo link above to see changes. Closing this issue here since I'd need to take this up with the Typescript team to get further with it

mosesoak avatar Feb 09 '18 22:02 mosesoak

@mosesoak Thanks for the workaround, using it for now. Was there a ticket raised on the TS repo I can follow regarding the changes discussed above?

liamjones avatar Apr 24 '18 09:04 liamjones

@liamjones I found some discussion here: https://github.com/Microsoft/TypeScript/issues/8328

ds300 avatar Apr 24 '18 10:04 ds300