ts-transformer-properties-rename icon indicating copy to clipboard operation
ts-transformer-properties-rename copied to clipboard

Return type of public function is marked as internal

Open meskill opened this issue 3 years ago • 1 comments

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',
  };
}

meskill avatar Dec 27 '21 15:12 meskill

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.

timocov avatar Jan 02 '22 16:01 timocov