Skip to content

Generic loses generic behaviour under certain conditions. #56377

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
coolCucumber-cat opened this issue Nov 13, 2023 · 2 comments
Closed

Generic loses generic behaviour under certain conditions. #56377

coolCucumber-cat opened this issue Nov 13, 2023 · 2 comments
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed

Comments

@coolCucumber-cat
Copy link

πŸ”Ž Search Terms

generics, generic loses genericness, generics with object types

πŸ•— Version & Regression Information

  • This is the behavior in every version I tried, and I reviewed the FAQ for entries about generics

⏯ Playground Link

https://www.typescriptlang.org/play?ts=5.3.0-beta#code/C4TwDgpgBAslC8UDeAoAkAQwFzKgEw2GygHIMSoBfdAIxyX0OJJourQGN7GicSO2KaigBmAVwB2HYAEsA9hKgSAPAHkoEAB7AIEvAGcoAawgg5I2AD4AFHJyqAlDhgBtVQF0XJAkRLvk6ABOEMBigYpkJEIoKBLWLCQOKEA

πŸ’» Code

type M = {
	a: { data: 'a' }
	b: { data: 'b' }
	c: { data: 'c' }
}

function n<O extends keyof M>(o: O): M[O]['data'] {
	return 'a' // expected error
}

n('b')

πŸ™ Actual behavior

It allows 'a', 'b' or 'c' instead of the generic type which is supposed to be the same as the input. The same problem occurs with assigning variables or functions inside the other function. Although the type must be M[O]['data'] and it says that it is that, it acts as if it were no longer generic, as in M[keyof M]['data'].

πŸ™‚ Expected behavior

I woud expect it to be M[O]['data'].

Additional information about the issue

You don't have this issue if you remove the object with the data key and replace it with the value of data, for example ''a' instead of { data: 'a'}

@IllusionMH
Copy link
Contributor

Related to #27808

@RyanCavanaugh
Copy link
Member

This is the best we have at the moment, since doubly-higher-order indexed operations aren't deferred. If this were an error, we'd have an error on a legal function body:

type M = {
	a: { data: 'a' }
	b: { data: 'b' }
	c: { data: 'c' }
}

declare const m: M;
function n<O extends keyof M>(o: O): M[O]['data'] {
	let t1 = m[o];
	//  ^? t1: M[O]
	let t2 = t1.data;
	//  ^? t2: 'a' | 'b' | 'c'
	return t2;
}

n('b')

You could rewrite this in terms of a conditional type, but at then point then there's no cast-free legal implementation of n

@RyanCavanaugh RyanCavanaugh added the Design Limitation Constraints of the existing architecture prevent this from being fixed label Nov 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Design Limitation Constraints of the existing architecture prevent this from being fixed
Projects
None yet
Development

No branches or pull requests

3 participants