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

Support export { x as default } in namespace declarations #24164

Open
bluelovers opened this issue May 16, 2018 · 7 comments
Open

Support export { x as default } in namespace declarations #24164

bluelovers opened this issue May 16, 2018 · 7 comments
Labels
In Discussion Not yet reached consensus Suggestion An idea for TypeScript

Comments

@bluelovers
Copy link
Contributor

Search Terms

Suggestion

options for allow use import { xxx } from 'yyy'; when TS2497 resolves to a non-module entity

without warn or use // @ts-ignore

Error:(11, 19) TS2305: Module has no exported member 'isGitRoot'.
Error:(11, 36) TS2497: Module resolves to a non-module entity and cannot be imported using this construct.

Use Cases

Examples

demo.ts

import gitRoot, { isGitRoot } from 'git-root2';

git-root2

declare function gitRoot(cwd?: string): string;
declare namespace gitRoot {
    function isGitRoot(target: string): boolean;
    function async(cwd?: string): Promise<string>;
}
declare const _default: typeof gitRoot & {
    gitRoot(cwd?: string): string;
    default(cwd?: string): string;
    async(cwd?: string): Promise<string>;
};
export = _default;

Checklist

My suggestion meets these guidelines:
[x] This wouldn't be a breaking change in existing TypeScript / JavaScript code
[x] 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. new expression-level syntax)

@mhegazy
Copy link
Contributor

mhegazy commented May 16, 2018

So the request is to enable someting like:

function gitRoot(cwd?: string): string {
    return null;
}

namespace gitRoot {
    export function isGitRoot(target: string) {
    }
    export { gitRoot as gitRoot };
    export { gitRoot as default };
    export const __esModule = true;
}

export = gitRoot;

@mhegazy mhegazy added Suggestion An idea for TypeScript In Discussion Not yet reached consensus labels May 16, 2018
@mhegazy mhegazy changed the title Feature request: options for allow use import { xxx } from 'yyy'; when TS2497 resolves to a non-module entity Support export { x as default } in namespace declarations May 16, 2018
@bluelovers
Copy link
Contributor Author

my another try

yargs2.ts

import yargs = require('yargs');
import Argv from './core';
export * from './core'; // got overwrite at runtime, but make import didn't have error

Argv(process.argv.slice(2), undefined, {
	supportPassArgs: true,
});

// @ts-ignore
export = Argv;

runtime source of yargs2.js

"use strict";
/**
 * Created by user on 2018/6/1/001.
 */
function __export(m) {
    for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
const core_1 = require("./core");
__export(require("./core"));
core_1.default(process.argv.slice(2), undefined, {
    supportPassArgs: true,
});
module.exports = core_1.default;

demo.ts

//import yargs = require('..'); // work
import * as yargs from '..' // work too
import { argv } from 'yargs2' // <=== ts don't know what can import , but without error

console.log(yargs.processArgs);
console.log(yargs.argv); // <=== ts know what `yargs.argv` is

console.log(argv); // <=== ts know what `argv` is

2018-06-01-16-34-43-1

@bluelovers
Copy link
Contributor Author

looks like this a little near


index.ts

import { Trie } from './src/trie'
// @ts-ignore
import { AhoCorasick } from './src/ahocorasick'

// @ts-ignore
export { AhoCorasick, Trie }

// @ts-ignore
export default AhoCorasick

// @ts-ignore
export = AhoCorasick

exports = Object.assign(AhoCorasick, exports);

index.d.ts

import { Trie } from './src/trie';
import { AhoCorasick } from './src/ahocorasick';
export { AhoCorasick, Trie };
export default AhoCorasick;
export = AhoCorasick;

index.js

const trie_1 = require("./src/trie");
// @ts-ignore
const ahocorasick_1 = require("./src/ahocorasick");
// @ts-ignore
exports.default = ahocorasick_1.AhoCorasick;
exports = Object.assign(ahocorasick_1.AhoCorasick, exports);
module.exports = ahocorasick_1.AhoCorasick;

temp.ts

import * as AhoCorasick from '..';
import AhoCorasick2 from '..';
import AhoCorasick3 = require('..');

let a1 = new AhoCorasick;
let a2 = new AhoCorasick2;
let a3 = new AhoCorasick3;

let a11 = new AhoCorasick();
let a22 = new AhoCorasick2();
let a33 = new AhoCorasick3();

console.log(a1);
console.log(a2);
console.log(a3);

console.log(a11);
console.log(a22);
console.log(a33);

@bluelovers
Copy link
Contributor Author

still hope can have this

@bluelovers
Copy link
Contributor Author

bluelovers commented Mar 2, 2019

declare function sortObject<T>(object: T, options?: sortObject.IOptions & {
    useSource: true;
}): T;
declare namespace sortObject {
    var default: typeof sortObject;
}
Error:(5, 9) TS1134: Variable declaration expected.

@bluelovers
Copy link
Contributor Author

bluelovers commented Mar 26, 2019

1 ~ 3 only can output work to .d.ts

1 will compile nothing in .js , but we can hack it for work
2 will compile bad .js, can't do any hack
3 looks like esm style, so it is bad .js too, can't do any hack

4 is work both of .js and .d.ts, but still hope one of 1~3 is can work, because 4 only work for function

1

1.1

when namespace is declare namespace and namespace name not same as something

export { something as default } is no error


1.2

when namespace is namespace

export { something as default } is error

=>

.js

(function (_CallClassWithoutNewDecorator) {
})(_CallClassWithoutNewDecorator || (_CallClassWithoutNewDecorator = {}));

.d.ts

in 1.1 or 1.2 .d.ts will output like this

export { callClassWithoutNewDecorator as default };

2

this is error too, but can output type

export default = callClassWithoutNewDecorator

=>

.d.ts

    const _default: typeof callClassWithoutNewDecorator;
    export default _default;

.js

(function (_CallClassWithoutNewDecorator) {
    export default  = callClassWithoutNewDecorator;
})(_CallClassWithoutNewDecorator || (_CallClassWithoutNewDecorator = {}));

3

export default callClassWithoutNewDecorator still error

=>

.d.ts

export default callClassWithoutNewDecorator;

.js

(function (_CallClassWithoutNewDecorator) {
    export default callClassWithoutNewDecorator;
})(_CallClassWithoutNewDecorator || (_CallClassWithoutNewDecorator = {}));

4

only for callClassWithoutNewDecorator is function

.ts

callClassWithoutNewDecorator.default = callClassWithoutNewDecorator;

=>

.d.ts

declare namespace callClassWithoutNewDecorator {
    var default: typeof callClassWithoutNewDecorator;
}

.js

callClassWithoutNewDecorator.default = callClassWithoutNewDecorator;

@bluelovers
Copy link
Contributor Author

still need can use default in namespace/module in .ts

because by some reason (performance), for ide

typeof xxx, and function xxx is not same thing

#28018

https://youtrack.jetbrains.com/issue/WEB-35879

https://youtrack.jetbrains.com/issue/WEB-37873

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
In Discussion Not yet reached consensus Suggestion An idea for TypeScript
Projects
None yet
Development

No branches or pull requests

2 participants