GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Add a new compiler option `moduleSuffixes` to expand the node module resolver's search algorithm by afoxman · Pull Request #48189 · microsoft/TypeScript

Conversation

@afoxman

@afoxman Adam Foxman (afoxman) commented Mar 9, 2022

Copy link
Copy Markdown
Contributor

This PR expands the node module resolver's search algorithm to include a list of module suffixes:

// react-native use-case: import './foo' -> search for foo.ios.ts, then foo.native.ts, and finally foo.ts
{
    "compilerOptions": {
        // empty string --> match without an extension
        "moduleSuffixes": [".ios", ".native", ""]
    }
}

// alternative use-case: import 'foo' -> search for foo-primary.ts, then foo__alt.ts (stop there)
{
    "compilerOptions": {
        "moduleSuffixes": ["-primary", "__alt"]
    }
}

This impacts all TypeScript workflows, including build and parsing for IntelliSense.

Developers who take advantage of this would have one tsconfig file per moduleSuffix list. The config file name should not be constrained to any particular pattern. Many 3rd-party tools already support specifying a tsconfig file name, explicitly, which makes this approach a good choice.

IntelliSense will need additional support to make this work. With multiple tsconfigs in play, IntelliSense will need to be told which one to use, or it will default to loading tsconfig.json. For the react-native use-case, I'm imagining this will be an IDE extension that exposes a platform selector in its config and/or in the UI. The corresponding tsconfig for that platform is passed to the IntelliSense tsserver process.

Fixes #21926

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

kelset, sidferreira, ecreeth, troZee, matijagrcic, Titozzz, shirakaba, anuraghazra, worstpractice, ricmatsui, and 4 more reacted with thumbs up emoji tido64, sidferreira, aleclarson, troZee, iRoachie, fluiddot, dcalhoun, fbartho, Titozzz, shirakaba, and 4 more reacted with hooray emoji sidferreira, ACHP, troZee, matijagrcic, fluiddot, dcalhoun, Titozzz, shirakaba, rkrupinski, KBSchmidt, and 5 more reacted with heart emoji
All reactions
  • 👍 14 reactions
  • 🎉 14 reactions
  • ❤️ 15 reactions
Adam Foxman (afoxman) added 2 commits March 8, 2022 20:58
@afoxman
Add moduleSuffixes compiler option and related tests. Update baseline…
6fc83e7
…s for compiler options tests.
@afoxman
Add a flag to the command-line parser which allows "list" params to p…
866ab7b
…reserve "falsy" values such as empty strings. Falsy values are normally stripped out.
@typescript-bot

TypeScript Bot (typescript-bot) commented Mar 9, 2022

Copy link
Copy Markdown
Contributor

The TypeScript team hasn't accepted the linked issue #21926. If you can get it accepted, this PR will have a better chance of being reviewed.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@typescript-bot TypeScript Bot (typescript-bot) added the For Uncommitted Bug PR for untriaged, rejected, closed or missing bug label Mar 9, 2022
@afoxman Adam Foxman (afoxman) mentioned this pull request Mar 9, 2022
Design Meeting Notes, 3/2/2022 #48095
Closed
@afoxman
Merge remote-tracking branch 'origin/main' into module-suffix
6fde83e
@sandersn
Nathan Shively-Sanders (sandersn) requested review from Andrew Branch (andrewbranch) and Sheetal Nandi (sheetalkamat) and removed request for Andrew Branch (andrewbranch) March 17, 2022 16:54
@sandersn Nathan Shively-Sanders (sandersn) assigned Andrew Branch (andrewbranch) Mar 17, 2022
@sandersn
Nathan Shively-Sanders (sandersn) requested a review from Andrew Branch (andrewbranch) March 17, 2022 16:54
sheetalkamat
Sheetal Nandi (sheetalkamat) requested changes Mar 17, 2022
View reviewed changes
Comment thread src/testRunner/unittests/config/convertCompilerOptionsFromJson.ts Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread src/compiler/moduleNameResolver.ts Resolved

Uh oh!

There was an error while loading. Please reload this page.

andrewbranch
Andrew Branch (andrewbranch) requested changes Mar 17, 2022
View reviewed changes
Comment thread tests/cases/compiler/moduleResolutionWithSuffixes_threeLastIsBlank4.ts Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread src/compiler/moduleNameResolver.ts Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread tests/cases/compiler/moduleResolutionWithSuffixes_threeLastIsBlank3.ts Resolved

Uh oh!

There was an error while loading. Please reload this page.

@andrewbranch

Andrew Branch (andrewbranch) commented Mar 17, 2022

Copy link
Copy Markdown
Member

Oops, some of my suggestions are redundant with Sheetal Nandi (@sheetalkamat)’s; her review came in while I was still browsing 😄

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

Adam Foxman (afoxman) added 2 commits March 18, 2022 11:23
@afoxman
Merge remote-tracking branch 'origin/main' into module-suffix
0d45cb6
@afoxman
Add tests. Rework resolver logic to only run module-suffix code when …
c11bea7
…needed.
This was referenced Mar 20, 2022
Metro+TS: support additional package.json fields when resolving a module to a file microsoft/rnx-kit#805
Closed
TypeScript support for react-native microsoft/rnx-kit#1273
Closed
sheetalkamat
Sheetal Nandi (sheetalkamat) requested changes Mar 22, 2022
View reviewed changes
Comment thread src/compiler/moduleNameResolver.ts Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread src/compiler/moduleNameResolver.ts Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread src/compiler/moduleNameResolver.ts Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread src/compiler/types.ts Resolved

Uh oh!

There was an error while loading. Please reload this page.

Comment thread src/compiler/types.ts Resolved

Uh oh!

There was an error while loading. Please reload this page.

Adam Foxman (afoxman) added 2 commits March 22, 2022 14:26
@afoxman
PR feedback
407f33f
@afoxman
Add test
682b687
andrewbranch
Andrew Branch (andrewbranch) approved these changes Mar 22, 2022
View reviewed changes
Comment thread src/compiler/commandLineParser.ts Resolved

Uh oh!

There was an error while loading. Please reload this page.

@afoxman
Remove unnecessary conditional.
5a6026f
sheetalkamat
Sheetal Nandi (sheetalkamat) reviewed Mar 23, 2022
View reviewed changes
Comment thread src/compiler/commandLineParser.ts

function convertJsonOptionOfListType(option: CommandLineOptionOfListType, values: readonly any[], basePath: string, errors: Push<Diagnostic>): any[] {
return filter(map(values, v => convertJsonOption(option.element, v, basePath, errors)), v => !!v);
return filter(map(values, v => convertJsonOption(option.element, v, basePath, errors)), v => option.listPreserveFalsyValues ? true : !!v);

@sheetalkamat Sheetal Nandi (sheetalkamat) Mar 23, 2022

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think instead of this we should just check if option is defined and get rid of listPreserveFalsyValues

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@afoxman Adam Foxman (afoxman) Mar 23, 2022

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That would change the behavior of other lists, like types, which could impact existing projects. Why risk exposing them?

To be clear what you're looking for, the filter condition would become v => v !== undefined?

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions

@afoxman Adam Foxman (afoxman) Mar 25, 2022

Copy link
Copy Markdown
Contributor Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sheetal Nandi (@sheetalkamat) Would you like to make this change, or is the risk of impacting existing projects too great? Please advise.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
sheetalkamat
Sheetal Nandi (sheetalkamat) approved these changes Mar 30, 2022
View reviewed changes
@andrewbranch

Andrew Branch (andrewbranch) commented Mar 30, 2022

Copy link
Copy Markdown
Member

Thanks Adam Foxman (@afoxman)!

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@andrewbranch
Andrew Branch (andrewbranch) merged commit 41aca7c into microsoft:main Mar 30, 2022
@mchowning Matt Chowning (mchowning) mentioned this pull request Mar 30, 2022
Refactor @wordpress/components package to TypeScript WordPress/gutenberg#35744
Closed
@sebmarkbage Sebastian Markbåge (sebmarkbage) mentioned this pull request Mar 31, 2022
RFC: React Server Module Conventions reactjs/rfcs#189
Closed
Sidharth Vinod (sidharthv96) added a commit to sidharthv96/TypeScript that referenced this pull request Apr 1, 2022
@sidharthv96
Merge remote-tracking branch 'upstream/main' into fix/46149
e149cc3
* upstream/main: (473 commits)
  Correct node used for isDefinition calculation (microsoft#48499)
  fix(48405): emit dummy members from a mapped type (microsoft#48481)
  CFA for dependent parameters typed by generic constraints (microsoft#48411)
  No contextual typing from return types for boolean literals (microsoft#48380)
  fix(47733): omit JSDoc comment template suggestion on node with existing JSDoc (microsoft#47748)
  Ensure that we copy empty NodeArrays during transform (microsoft#48490)
  Add a new compiler option `moduleSuffixes` to expand the node module resolver's search algorithm (microsoft#48189)
  feat(27615): Add missing member fix should work for type literals (microsoft#47212)
  Add label details to completion entry (microsoft#48429)
  Enable method signature completion for object literals (microsoft#48168)
  Fix string literal completions when a partially-typed string fixes inference to a type parameter (microsoft#48410)
  fix(48445): show errors on type-only import/export specifiers in JavaScript files (microsoft#48449)
  Fix newline inserted in empty block at end of formatting range (microsoft#48463)
  Prevent looking up symbol for as const from triggering an error (microsoft#48464)
  Revise accessor resolution logic and error reporting (microsoft#48459)
  fix(48166): skip checking module.exports in a truthiness call expression (microsoft#48337)
  LEGO: Merge pull request 48450
  LEGO: Merge pull request 48436
  fix(48031): show circularity error for self referential get accessor annotations (microsoft#48050)
  Revert "Fix contextual discrimination for omitted members (microsoft#43937)" (microsoft#48426)
  ...
@cccRaim 陈然 (cccRaim) mentioned this pull request Jul 28, 2022
generated output don't follow moduleSuffixes option #49586
Closed
@kylemh Kyle Holmberg (kylemh) mentioned this pull request Nov 2, 2022
Support for multiple, root-level tsconfigs #51382
Closed
@jircdev

Julio Rodriguez (jircdev) commented Nov 15, 2022

Copy link
Copy Markdown

I think this option is very useful, but thinking about it, I have two questions:
There is a way as a consumer to know what bundle I need to consume?

The other stuff is: There may be cases where a module's interface changes depending on the compiled platform, such as IDEs or text editors identifying the types to use

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@afoxman
Adam Foxman (afoxman) deleted the module-suffix branch November 15, 2022 06:01
@afoxman

Adam Foxman (afoxman) commented Nov 15, 2022

Copy link
Copy Markdown
Contributor Author

Hi Julio Rodriguez (@jircdev), I think your questions fall into the realm of React Native, so I'll answer in that context.

I think this option is very useful, but thinking about it, I have two questions: There is a way as a consumer to know what bundle I need to consume?

It's up to the package producer to establish any rules about which artifacts apply to which platform.

The other stuff is: There may be cases where a module's interface changes depending on the compiled platform, such as IDEs or text editors identifying the types to use

Yes, this is a problem that has yet to be solved. IDEs like VS Code would benefit from having a platform selector which influences how modules (and therefore types) are resolved for browsing. This is a big undertaking, and will require a VS Code plugin and some changes to the TypeScript Server. I don't think it's APIs have enough flexibility to support this scenario.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@jircdev

Julio Rodriguez (jircdev) commented Nov 18, 2022

Copy link
Copy Markdown

Hi Adam Foxman (@afoxman),

I believe I was not clear enough before with the first point, let me clarify it;

Hi Julio Rodriguez (@jircdev), I think your questions fall into the realm of React Native, so I'll answer in that context.

I think this option is very useful, but thinking about it, I have two questions: There is a way as a consumer to know what bundle I need to consume?

It's up to the package producer to establish any rules about which artifacts apply to which platform.

I know it not depends on Typescript or React Native but I want to know your opinion.

If I am the creator of a package which I end up building for two platforms (ios and android), How can the dev tools that need to consume this package identify which file must be considered and included? or How can Typescript which is the declaration type to take as valid?

In the NodeJS documentation, they talk about conditional exports and the possibility of adding multiple "target platforms", such as Node, Browser, or Deno but they do include ios or android (that is a requirement beyond of React Native). I think we may use this entry point (conditional exports) to solve the problem in a standardized way and take advantage of it to specify that kind of requirement.

What is your opinion?

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@afoxman

Adam Foxman (afoxman) commented Nov 21, 2022

Copy link
Copy Markdown
Contributor Author

If I am the creator of a package which I end up building for two platforms (ios and android), How can the dev tools that need to consume this package identify which file must be considered and included? or How can Typescript which is the declaration type to take as valid?

In the NodeJS documentation, they talk about conditional exports and the possibility of adding multiple "target platforms", such as Node, Browser, or Deno but they do include ios or android (that is a requirement beyond of React Native). I think we may use this entry point (conditional exports) to solve the problem in a standardized way and take advantage of it to specify that kind of requirement.

What is your opinion?

Node's conditional exports talk about "environment", not "platform", and the examples of default, production, and development suggest this needs to stay separate from the concept of a platform.

I deliberately avoided codifying a standard or even a suggestion about how a React Native package would export both ios and android built artifacts (e.g. transformed TS/Flow files, assets, etc). Getting to a decision there requires broad consensus, and probably a set of working/proven packages that are successfully demonstrating it.

If I had to guess at how it might work, I think the answer starts in react-native.config.js. This is specific to React Native, which makes it appropriately scoped. And there is room in there for platform-specific information. The config schema is defined as part of the React Native CLI. But there is nothing in config today which attempts to define "build artifacts" for a platform+package. So you'd be breaking new ground.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@microsoft Microsoft (microsoft) locked as resolved and limited conversation to collaborators Oct 22, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Reviewers

@andrewbranch Andrew Branch (andrewbranch) andrewbranch approved these changes
@sheetalkamat Sheetal Nandi (sheetalkamat) sheetalkamat approved these changes

Uh oh!

There was an error while loading. Please reload this page.

Assignees

@andrewbranch Andrew Branch (andrewbranch)

Labels

For Uncommitted Bug PR for untriaged, rejected, closed or missing bug

Projects

PR Backlog
Archived in project

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Proposal: Allow typescript to type check modules using react-native's module resolution

Uh oh!

There was an error while loading. Please reload this page.

5 participants

@afoxman @typescript-bot @andrewbranch @jircdev @sheetalkamat
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402503 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.