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

Return type of public function is marked as internal #27

Open
meskill opened this issue Dec 27, 2021 · 1 comment · May be fixed by #28
Open

Return type of public function is marked as internal #27

meskill opened this issue Dec 27, 2021 · 1 comment · May be fixed by #28
Labels
bug Something isn't working

Comments

@meskill
Copy link

meskill commented Dec 27, 2021

Bug report

When I do not specify return type to public functions the returning literal object is transformed to the object with internal properties.

Input code

function fn(input: { test1: number; test2: string }): { a: number; b: string } {
  return {
    a: 2,
    b: 'str',
  };
}

export function fn2(input: { test1: number; test2: string }) {
  const { a } = fn({ test1: 25, test2: 'test' });

  return {
    a,
    b: 'str',
  };
}

Expected output

function fn(input) {
    return {
        _internal_a: 2,
        _internal_b: 'str',
    };
}
function fn2(input) {
    const { _internal_a: a } = fn();
    return {
        a,
        b: 'str',
    };
}

export { fn2 };

Actual output

function fn(input) {
    return {
        _internal_a: 2,
        _internal_b: 'str',
    };
}
function fn2(input) {
    const { _internal_a: a } = fn();
    return {
        _internal_a: a,
        _internal_b: 'str',
    };
}

export { fn2 };

Additional context
If I specify return type explicitly it works as expected

function fn(input: { test1: number; test2: string }): { a: number; b: string } {
  return {
    a: 2,
    b: 'str',
  };
}

export function fn2(input: { test1: number; test2: string }): { a: number; b: string } { // this is the only change as return type is explicit now
  const { a } = fn({ test1: 25, test2: 'test' });

  return {
    a,
    b: 'str',
  };
}
@timocov timocov added the bug Something isn't working label Dec 28, 2021
@timocov
Copy link
Owner

timocov commented Jan 2, 2022

I'm afraid it might be impossible to fix this issue in general. The reason is duck typing. On the compiler level we just don't know if your object is related somehow (or declares anyhow) to a returned type. After quick look into the state of the program I didn't find a strong relation between a returned type and a type of a variable. Yes, we can try to rely of symbols of both of them, but even if they are the same now doesn't mean that they will be the same in the next versions and due duck typing they shouldn't be the same.

For example, for now it works for this code:

function privateFunctionWithDeclaredType() {
	return {
		f: 1,
		f2: 2,
	};
}
export function fn2() {
	return privateFunctionWithDeclaredType();
}

but if you extract a returned value to a variable inside privateFunctionWithDeclaredType it won't work

function privateFunctionWithDeclaredType() {
	const result = {
		f: 1,
		f2: 2,
	};

	return result;
}
export function fn2() {
	return privateFunctionWithDeclaredType();
}

That's because const result has no relation to a returned value's type, they are similar (or the same, or narrowed one from another) in terms of duck typing but they aren't the same (even adding a unnamed returned type to a function might break it).

Probably after #14 it could be a bit better since the tool won't rely on types and will use names only, but it won't produce the same level of minifying.

I'll partially fix this issue soon, but this thing is a bit dangerous and I'd say that it's better to specify an API explicitly when it's possible.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
2 participants