Skip to content

Index Signatures break Mapped type key picking. #30293

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
jasonswearingen opened this issue Mar 9, 2019 · 4 comments
Closed

Index Signatures break Mapped type key picking. #30293

jasonswearingen opened this issue Mar 9, 2019 · 4 comments
Labels
Question An issue which isn't directly actionable in code

Comments

@jasonswearingen
Copy link

jasonswearingen commented Mar 9, 2019

Update: Please see the second comment, titled "simple repro"

Summary

I'm trying to create type definitions for a mixin object. when doing so I found the following error if one of the mixed types has an index signature.

removing the index signature "fixes" the problem.

TypeScript Version: 3.3.3333

Code

/** helper that returns prop names except those to filter.  This helper type is needed to actually remove the prop, as otherwise the prop still exists in the type just as "never".  */
type PropsRemove_Name<TTarget, TPropToRemove> = { [ K in keyof TTarget ]: TTarget[ K ] extends TPropToRemove ? never : K }[ keyof TTarget ];
/** remove props of the given type.   always removes ```never``` type props.  if no ```TPropToRemove``` is provided, removes just ```never``` type props. */
type PropsRemove<TTarget,TPropToRemove=never> = Pick<TTarget, PropsRemove_Name<TTarget,TPropToRemove>>;

/** type used to demonstrate the bug */
type TestType = {
	a: number;
} & {	
	b: boolean;
	[ key: string ]: boolean; //THE OFFENDING LINE
}

let testRemoval: PropsRemove<TestType,number>;

Expected behavior:

//expect typescript to provide the proper definition. 
testRemoval.b; //boolean

Actual behavior:

//with the index signature, typescript provides no properties in the dropdown
testRemoval; //no properties

//when the index signature is removed, typescript provides the proper definition. 
testRemoval.b; //boolean

Related Issues: didn't really see any :(

@jasonswearingen
Copy link
Author

jasonswearingen commented Mar 9, 2019

simple repro:

/** type used to demonstrate the bug */
type TestType ={
	b: boolean;
	[ key: string ]: boolean;
}

let testSimple: Pick<TestType, keyof TestType>;
testSimple; //no properties in vscode intellisense dropdown, nor available in type propagation (unioning, etc).  comment the index signature to get properties.

@jasonswearingen jasonswearingen changed the title Index Signatures break Distributive conditional types. Index Signatures break Mapped types. Mar 9, 2019
@jasonswearingen jasonswearingen changed the title Index Signatures break Mapped types. Index Signatures break Mapped type key picking. Mar 9, 2019
@jack-williams
Copy link
Collaborator

This is related to: #17867

@RyanCavanaugh RyanCavanaugh added the Question An issue which isn't directly actionable in code label Mar 19, 2019
@RyanCavanaugh
Copy link
Member

keyof TestType is string | number

Pick<TestType, string | number> is { [k: string]: boolean }

I think both of those are fairly inarguable given the definition of both operations. Pick<T, keyof T> is not guaranteed to produce T for this reason.

@jasonswearingen
Copy link
Author

sorry @RyanCavanaugh, not following you, I don't spend enough time with type definitions I guess :/

Maybe my "simple" repro muddys the issue. I want to do as shown in the initial post: remove a property, but can not when an index signature is in the type.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Question An issue which isn't directly actionable in code
Projects
None yet
Development

No branches or pull requests

4 participants