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:
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:
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.
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?
@liamjones I found some discussion here: microsoft/TypeScript#8328