blakeembrey / tslint-config-standard

A TSLint config for JavaScript Standard Style
Other
358 stars 43 forks source link

Is it possible to satisfy the no-duplicate-imports rule with type imports? #41

Open garth opened 7 years ago

garth commented 7 years ago

Is it possible to import from both a node_module and type in a single import statement?

import * as React from 'react'; // import from module
import { StatelessComponent } from 'react'; // import from type
blakeembrey commented 7 years ago

Should be. Try import * as React, { StatelessComponent } from React.

garth commented 7 years ago

I don't think that is valid syntax.

blakeembrey commented 7 years ago

You're right, sorry. I'm not sure then. I'd just use destructing like normal:

import * as React from 'react'
const { StatelessComponent } = React
blakeembrey commented 7 years ago

If you'd like, feel free to verify the behaviour is the same as with StandardJS. They're using it from https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-duplicates.md, so there may be a deviation in TSLint if your code was valid with ESLint.

garth commented 7 years ago

I think the rule is valid for js, just not sure it should be applied to ts. I have disabled the rule in local config, but I would be interested to see if there is a better solution.

blakeembrey commented 7 years ago

Both imports are identical in JS vs TS, there's no real difference. If what you mean is about StatelessComponent as a type, you can import from a namespace but it sadly gets ugly. Try this:

namespace React {
    export interface StatelessComponent { }
}

import StatelessComponent = React.StatelessComponent

This would be improved 10x if TypeScript supported destructing in this case, which i think is pretty important for property parity with JS nowadays (e.g. import { Component } = require('react') should be allowed by TypeScript too, but the only allow import React = require('react')).

blakeembrey commented 7 years ago

Ah, sorry, I just saw you were talking about type imports in the title 😄 I regularly overlook the title and just read the body, sorry for the confusion and oversight.

Hotell commented 6 years ago

@garth what you should do in case of importing react stuff is following:

tsonfig:

{
  "compileOptions": {
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true
  }
}

now you can:

import React, { StatelessComponent } from 'react';

PRO TIP: instead of importing super long/verbose StatelessComponent use SFC type alias

PRO TIP 2: We've gone even further and import only what the module needs. So for transforming JSX to function calls we import only createElement

// now you got both runtime function and typescript type in one import
import {createElement, SFC} from 'react'

tsonfig:

{
  "compileOptions": {
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "jsx": "react",
    "jsxFactory": "createElement",
  }
}

or since TS 2.9 you can import types inline where your need them, so you solely import only runtime values via standard ES2015 modules

import React from 'react'

type Props = {...}
const Hello: import('react').SFC<Props> = (props) => <div>Hello</div>