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

Custom Type Declaration Resolver #29440

Closed
5 tasks done
Cryrivers opened this issue Jan 16, 2019 · 7 comments
Closed
5 tasks done

Custom Type Declaration Resolver #29440

Cryrivers opened this issue Jan 16, 2019 · 7 comments
Labels
Duplicate An existing issue was already created

Comments

@Cryrivers
Copy link

Cryrivers commented Jan 16, 2019

Search Terms

custom type declaration resolver

Suggestion

Thanks to Webpack, we can import a various of file types by using loaders. svg-inline-loader, for example, reads svg files and outputs a JavaScript module so it can play with JavaScript well.

In TypeScript world, handling the type declaration for custom file types could be tricky. For the simple case mentioned-above, we can have ambient declarations like the following:

declare module '*.svg' {
  import { ComponentClass } from 'react';
  const content: ComponentClass<React.SVGAttributes<SVGElement>>;
  export default content;
}

But for things more dynamic, wasm, json, then this way doesn't work so well because it only provides very static typings.

Hence I propose to have a custom declaration resolving mechanism, introducing declaration resolver, which is like loaders to webpack but emits d.ts files. And a way to assign resolvers for different file extensions in tsconfig.json

Potentially it could replace resolveJsonModule because this one could be delivered as JSON declaration resolver.

Examples

// tsconfig.json
{
  "declarationResolvers": {
    "*.json": "json-declaration-resolver",
    "*.wasm": "wasm-declaration-resolver",
    "*.protobuf": "protobuf-declaration-resolver"
  }
}
import createInstance from './test.wasm';

// `createInstance` should get the correct typings due to `wasm-declaration-resolver`
createInstance().then(m => {
  console.log(m.instance.exports.add(1, 2));
  console.log(m.instance.exports.test());
});

Checklist

My suggestion meets these guidelines:

  • This wouldn't be a breaking change in existing TypeScript/JavaScript code
  • This wouldn't change the runtime behavior of existing JavaScript code
  • This could be implemented without emitting different JS based on the types of the expressions
  • This isn't a runtime feature (e.g. library functionality, non-ECMAScript syntax with JavaScript output, etc.)
  • This feature would agree with the rest of TypeScript's Design Goals.
@weswigham
Copy link
Member

For wasm, if you're using rust's wasm-bindgen to build the wasm, it produces declaration files for you, which is a really good idea - this captures for more of the nuance of the original input language than interpreting the wasm itself in some way would.

And we can already read the data/types from a .json file directly - just set the resolveJsonModule flag.

@Cryrivers
Copy link
Author

I think you are right. But currently resolveJsonModule is very restrictive. You need to set module to commonjs to make it work.

@ajafff
Copy link
Contributor

ajafff commented Jan 16, 2019

This feature request looks similar to #3136

@weswigham weswigham added the Duplicate An existing issue was already created label Jan 17, 2019
@weswigham
Copy link
Member

Yeah, definitely is contained within #3136 at core. But to anyone who finds this: If you can do codegen (because for example the thing you're trying to import types for comes from another build process), it's probably a better choice than trying to inject dynamically generated types into a program.

@Jessidhia
Copy link

This would be very useful for .vue and .css (module) files. For .css doing codegen is probably still acceptable, but .vue files really need some kind of first party (or pluggable) support in order to work.

Right now with editor plugins such as vetur it's possible to run typescript within the typescript section of a .vue file itself, but importing a .vue file still just gives you whatever the declare module '*.vue' is.

@Cryrivers
Copy link
Author

Cryrivers commented Jan 18, 2019

My mind might be unclear when I was creating this ticket. We mostly use codegen to type other file types, *.css, *.svg etc, which is quite acceptable to us.

However, recently we import protocol buffers to our project as well. Codegen is not ideal in this case because we need to generate a huge amount of code which has negative impact on performance to us. Therefore I'm thinking if we could have a way to translate other files (especially schemas) to type declaration on-the-fly (or is it more like a custom language service?).

Lines of type declaration generated by protobuf.js
image

@typescript-bot
Copy link
Collaborator

This issue has been marked as a 'Duplicate' and has seen no recent activity. It has been automatically closed for house-keeping purposes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Duplicate An existing issue was already created
Projects
None yet
Development

No branches or pull requests

5 participants