Skip to content

Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated #16786

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

Closed
alan-agius4 opened this issue Jun 28, 2017 · 11 comments
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug

Comments

@alan-agius4
Copy link
Contributor

TypeScript Version: 2.4.1

Code

interface myModel {
	prop: <T>(update: T) => void;
}

class myClass {
	test<T>(model: T) {
		const x = {
			prop: (model: T) => {
				// do something
			}
		}
		this.test2(x);
	}

	test2(model: myModel) {
		
	}
}

Expected behavior:
no errors

Actual behavior:
Type 'T' is not assignable to type 'T'. Two different types with this name exist, but they are unrelated.

@alan-agius4
Copy link
Contributor Author

alan-agius4 commented Jun 28, 2017

I also have the same error using rxjs

(operator: Operator<any, Action>) => Observable<Action>' is not assignable to type '<R>(operator: Operator<any, R>) => Observable<R>

@dozer75
Copy link

dozer75 commented Jun 28, 2017

Also get the same error in the latest typescript release on rxjs.

I really starting to be frustrated over open source and the lack of quality checking on releases in different open source projects.

@HerringtonDarkholme
Copy link
Contributor

HerringtonDarkholme commented Jun 28, 2017

TypeScript did find a bug in your code.

interface myModel {
	prop: <T>(update: T) => void;
}

The generic signature means myModel can accept "universally any" type. Because the type parameter T here is totally free, without any constraint.

However, in myClass.

test<T>(model: T) {
		const x = {
			prop: (model: T) => { 
                                  // T here is a usage, it refers to the type parameter above.
                                  // x.prop only accept the type `T`, which might be  `string`
			}
		}
		this.test2(x);
	}
test2(model: mymodel) {
        model.prop(123) // x might only accept `string`, but passed number
}

Note the comment, T is not free, it is "bound" to the outer declaration.

It is hard to explain. But TS is right here.

@RyanCavanaugh RyanCavanaugh added the Working as Intended The behavior described is the intended behavior; this is not a bug label Jun 28, 2017
@alan-agius4
Copy link
Contributor Author

alan-agius4 commented Jun 28, 2017 via email

@RyanCavanaugh
Copy link
Member

The intent of prop: <T>(update: T) => void; is very unclear. There's not really anything distinguishing it from prop: (update: { }) => void; or prop: (update: any) => void; other than it looking more typesafe than it actually is.

@ahejlsberg
Copy link
Member

See #16368 for more context. Note that you can use the --noStrictGenericChecks to turn off the new stricter checks as a stopgap solution.

@alan-agius4
Copy link
Contributor Author

alan-agius4 commented Jun 28, 2017 via email

@mhegazy
Copy link
Contributor

mhegazy commented Aug 17, 2017

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

@khanhhc
Copy link

khanhhc commented Jan 25, 2018

Why this bug is not fixed?????

@dave0688
Copy link

+1
Still having the bug... Why is it not adressed yet??

@ahejlsberg
Copy link
Member

This is working as intended. It so happens there are two type parameters named T in the example, but they're distinct and not assignment compatible.

@microsoft microsoft locked and limited conversation to collaborators Jul 3, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug
Projects
None yet
Development

No branches or pull requests

8 participants