-
Notifications
You must be signed in to change notification settings - Fork 12.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal: Allow typescript to type check modules using react-native's module resolution #21926
Comments
For the sake of my own context. Is this issue specifically rooted in the fact that metro is using their non standard haste module system? Or is this not entirely related. Or better yet, would this issue still occur if you are packaging/bundling your app using webpack to bundle which actually respects NodeJS's / or ESM module resolution system. |
This would still be based on Node's resolution strategy, but with platform-specific extensions in mind. It doesn't have any of the specific quirks of Haste, since that can usually be achieved via path mapping/aliasing. |
Please consider using a more abstract |
This feature is really wanted for react-native users. Our team use .native.ts, and .web.ts postfix rules if |
Any updates on this? It seems Typescript doesn't support the ".native.js" and ".web.js" loading mechanism in react-native. |
Just encountered this problem ourselves - VSCode is giving us suggestions based on our web components even in our Native code. |
I'm facing the same issue in our projects. We have a isomorphic application, and Typescript don't resolve ".web.js" extensions. |
bump, would love to see this! has anybody found a workaround for compile-time resolution? I'm aware of this approach using |
We're running into major problems in a react, react-native project that is supposed to share a lot of code and uses TypeScript. Because this feature is missing we're wondering if TS was the wrong decision. Did anyone manage to set TS up for this? |
I wasn't able to set up TypeScript for this, per se, but I did come up with a webpack-based solution that is perfectly acceptable. Here is my webpack config file as an example. It sets up a const path = require('path');
const createExpoWebpackConfigAsync = require('@expo/webpack-config');
module.exports = async function(env, argv) {
const config = await createExpoWebpackConfigAsync(env, argv);
// Customize the config before returning it.
const addAlias = (
moduleName,
moduleDir = 'mocked_modules',
moduleAlias = ''
) => {
config.resolve.alias[moduleName] = path.resolve(
__dirname,
`./${moduleDir}/${moduleAlias || moduleName}`
);
};
addAlias('react-native-email-link');
addAlias('sentry-expo');
addAlias('lottie-react-native');
addAlias(
'@use-expo/screen-orientation',
'mocked_modules',
'use-expo-screen-orientation'
);
addAlias('react-native');
return config;
}; With this, when I run Consideration: This is more of a polyfill approach where the declarations & types of the modules stay the same between platforms. TypeScript still pulls the types from |
Solution in the mean time is to include a ".d.ts" declaration file with the same name to inform typescript of the common interface |
I got TypeScript to work in ideal way, where running for my
"compilerOptions": {
"paths": {
"*": ["*.ios", "*.android", "*.native", "*/index.ios", "*/index.android", "*/index.native", "*"]
}, The extra Just cause if you're looking at this, chances are you are fighting with npx eslint ./src --ext .android.ts,.ios.ts,.native.ts,.android.tsx,.ios.tsx,.native.tsx,.js,.jsx,.ts,.tsx |
I forgot to add, I also had to create
import Text, {TextProps} from './Text.native';
export {TextProps};
export default Text; |
@acoates-ms thanks for creating this proposal. 🙇🏻 I noticed there hasn't been much activity on this topic. @DanielRosenwasser do you know if there is any specific work needed to move this proposal forward? Anything the community can contribute? Thank you! |
Based on @DanielRosenwasser's recent meeting notes, I've put together an implementation of this proposal which achieves the desired outcome for react-native while being more generally useful in other contexts. I'll be submitting a PR shortly and tying it to this proposal. Detailed explanation is here: https://github.com/afoxman/rnts-example#react-native-platform-extensions |
Proposal is to add a new command line parameter to tsc which provides a list of
resolutionPlatforms
. This is just an array of strings, that will be used during that invocation of tsc to do module resolution.You can then during your build invoke tsc once for each platform to do a complete static type check of the files that will actually get included by the metro-bundler.
This small change will allow developers to take existing typescript react-native projects which are not being properly typechecked due to metro-bundler's platform specific file resolution.
We have run this on our repo and found various bugs with the additional type checking.
This fixes the issue described in
#17681 which was closed due to no actionable solution.
The code for such a new parameter is relatively easy to add to typescript:
Here is a link to a branch based on 2.7.1 with the new parameter implemented.
acoates-ms@f023961
It also solves #8328 which has an incorrect solution of using the paths option, which doesn't work in a bunch of cases, such as relative path imports.
and was incorrectly marked as a dup of #420 , which isn't the same as that forces all the platforms to expose the same interface, which isn't what the bundler does.
Example build script to check multiple platforms:
TypeScript Version: 2.7.1
Search Terms: react-native platform resolution
Code
A.ts
B.ts
B.ios.ts
Expected behavior:
Type error when compiling for ios, since AComponent is not providing the required bar property.
Actual behavior:
tsc never checked B.ios.ts at all. -- So the code that gets included in the ios react-native bundle never gets checked as bundled.
Related Issues:
One issue this doesn't solve is cross package react-native platform resolution. If package C has A and B as above, but A exported B. Then A.d.ts would likely contain the incorrect information as its not clear
which version of B it would include. I think the next evolution of this change would be to have tsc output a separate A.ios.d.ts and A.android.d.ts when doing the platform specific builds. Thus ensuring that cross package type checking can also be done. This shouldn't be too hard to add, and would be completely additive to this change.
The text was updated successfully, but these errors were encountered: