ds300/react-native-typescript-transformer

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

mosesoak opened this issue ยท 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

^ made the repo public ๐Ÿ˜ฌ

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

ds300 commented

Sadly-Typed Components

๐Ÿ˜‚

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.

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

ds300 commented

@liamjones I found some discussion here: microsoft/TypeScript#8328