Skip to content
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

Add support for custom import handlers #11610

Closed
Systemcluster opened this issue Oct 14, 2016 · 7 comments
Closed

Add support for custom import handlers #11610

Systemcluster opened this issue Oct 14, 2016 · 7 comments
Labels
Duplicate An existing issue was already created

Comments

@Systemcluster
Copy link

Systemcluster commented Oct 14, 2016

Abstract

Provide a mechanism to let developers define custom import handlers to allow typesafe imports of different file types.

Problem

import at this time exclusively handles ts/js module imports. Importing non-modules, e.g. css (for css-modules usage) or json files, currently requires workarounds with potentially huge drawbacks: Statically creating a .d.ts for each file, or using a require declaration returning any.

    // examples using webpack css-loader in module mode
    import * as styles from "./style.css" // requires static style.css.d.ts
    const styles = require<any>("./style.css") // not type-checked

Proposition

Provide a mechanism to define import handlers for specified file extensions. This handler will be supplied with the path of the file to be imported, and shall return a valid declaration - from the scripts perspective, a custom import should behave like a regular typescript module import.

The handler could exist as a single script or a node module.

Advantages

The proposed addition opens up the possibility for developers to implement typesafe usage of loaders when using module bundlers like webpack. Additionally, it could enable the development of more flexible build pipelines that don't rely on preceding transpilation.

@aluanhaddad
Copy link
Contributor

aluanhaddad commented Oct 14, 2016

This has already been resolved with ambient wildcard module declarations. Unfortunately this does not validate the existence of the target but it allows you to specify the types of the values produced by the loaders and bundlers that operate over them.

Workarounds like creating individual .d.ts files were annoying and cumbersome to maintain, but are no longer necessary thanks to this new feature in 2.0.

declare module '*.html' {
  export default '';
}

What does does not do is intertwine TypeScript with a specific tool, environment, or protocol. It is an abstract declaration and can even contain exotic AMD style plug-in syntax or synthetic directory structures.

I think this turned out really well.

@kitsonk
Copy link
Contributor

kitsonk commented Oct 14, 2016

For reference the issue is #6615

@Systemcluster
Copy link
Author

Systemcluster commented Oct 14, 2016

Indeed wildcard module declarations are a good solution for many cases, but they do not provide a typesafe mechanism on a individual file basis. This would be an option separate to wildcard module declarations. Staying with the css-modules example, a pluggable import handler could enable the type checker to catch the following error:

    .elem {/* css declaration */}
    import * as styles from "styles.css"
    let e = styles.elm // typo, styles.elm is not defined

This would also be valuable for importing e.g. JSON files, which can contain properties of various types and thus greatly profit from being type checked.

@kitsonk
Copy link
Contributor

kitsonk commented Oct 14, 2016

What you are asking for is non trivial. These import handlers would have to parse non-TypeScript files into some sort of AST that is understood by TypeScript. That would require a whole syntactic language to describe how to parse files in other languages.

What we have been doing in @dojo, wanting to use CSS Modules, is creating a build step in our process to output a TypeScript module that contains the mapping of modular CSS classes into what is being generated when the CSS Module is transpiled. We are also doing something similar with our internationalisation strings.

We are finding that dynamically generating TypeScript files is one of the easiest ways to have TypeScript understand "foreign" file formats.

@Systemcluster
Copy link
Author

Systemcluster commented Oct 14, 2016

These import handlers would have to parse non-TypeScript files into some sort of AST that is understood by TypeScript. That would require a whole syntactic language to describe how to parse files in other languages.

They would return a simple module declaration in string form, the same format that a matching .d.ts file would contain. Typescript would then consume this string like any other module.

We are finding that dynamically generating TypeScript files is one of the easiest ways to have TypeScript understand "foreign" file formats.

This is what the handler is supposed to do, merely avoiding the detour of writing the generated typescript to a file and instead passing the contents directly to the typescript service. It would have the advantage of providing the definition immediately to enable on-the-fly type checking (and autocompletion), without the necessity of a separate build step.

@mhegazy
Copy link
Contributor

mhegazy commented Oct 17, 2016

I would recommend creating a tool that would generate a .d.ts file from the original file.

Building a whole set of custom module loading plugins, watching the source files, doing this on every edit would not be a salable solution.

@mhegazy
Copy link
Contributor

mhegazy commented Oct 17, 2016

I should also note this is already covered by #3136

@mhegazy mhegazy added the Duplicate An existing issue was already created label Oct 17, 2016
@mhegazy mhegazy closed this as completed Apr 21, 2017
@microsoft microsoft locked and limited conversation to collaborators Jun 19, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

4 participants