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

Error with this['prop'] type interacting with || operator #15376

Closed
adufilie opened this issue Apr 25, 2017 · 4 comments
Closed

Error with this['prop'] type interacting with || operator #15376

adufilie opened this issue Apr 25, 2017 · 4 comments
Labels
Duplicate An existing issue was already created

Comments

@adufilie
Copy link

adufilie commented Apr 25, 2017

TypeScript Version: 2.2.1, 2.3.0

Code

// A *self-contained* demonstration of the problem follows...
// Compiled with strictNullChecks=true
class Foo {
	test1(foo:string|undefined):string {
		return foo || 'default'; // no error
	}
	test2(params:{foo: string|undefined}):string {
		return params.foo || 'default'; // no error
	}
	test3(params:Pick<{foo: string|undefined}, 'foo'>):string {
		return params.foo || 'default'; // no error
	}

	foo:string|undefined;

	test4(params:Pick<this, 'foo'>):string {
	    return params.foo || 'default'; // error: undefined not assignable to string
	}
	test5(foo:this['foo']):string {
	    return foo || 'default'; // error: undefined not assignable to string
	}
	test6(foo:this['foo']):string {
	    return (foo as string|undefined) || 'default'; // no error
	}
}

Expected behavior:
Expected no errors because the type of the expression foo || 'default' should be string in all cases.

Actual behavior:
When a type is derived indrectly from this it seems to break the type inference of the || operator.

Error:(17, 6) TS2322:Type 'this["foo"]' is not assignable to type 'string'.
  Type 'string | undefined' is not assignable to type 'string'.
    Type 'undefined' is not assignable to type 'string'.
Error:(20, 6) TS2322:Type 'this["foo"]' is not assignable to type 'string'.
  Type 'string | undefined' is not assignable to type 'string'.
    Type 'undefined' is not assignable to type 'string'.
@mhegazy
Copy link
Contributor

mhegazy commented Apr 25, 2017

There is not a way currently to remove null/undefined from a generic type. when foo is defined to have the type this["foo"] it is considered generic, since this is the type of the most derived at instantiation time.

We need a type operator to be applied to the generic type in these narrowing conditions to remove null/undefined when the type is instantiated.

The underlying issue is tracked by #14366

@mhegazy mhegazy added the Duplicate An existing issue was already created label Apr 25, 2017
@adufilie
Copy link
Author

But in this case shouldn't it know that this is of type Foo and work exactly as if I had typed Foo["foo"]?

@mhegazy
Copy link
Contributor

mhegazy commented Apr 26, 2017

But in this case shouldn't it know that this is of type Foo and work exactly as if I had typed Foo["foo"]?

The compiler can not make that assumption,

class Bar extends Foo {
	foo:undefined;
}

now Bar is still a subtype of Foo but Bar.foo is the same as Foo.foo.

the result of the narrowing should be this["foo"]! where ! removes the null and undefined from the type when it is instantiated.

@mhegazy
Copy link
Contributor

mhegazy commented May 19, 2017

Automatically closing this issue for housekeeping purposes. The issue labels indicate that it is unactionable at the moment or has already been addressed.

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

No branches or pull requests

2 participants