-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Omit
helper loses type information when used with extended Records.
#36981
Comments
type AnyRecord = Record<string, any>;
interface ExtendsAny extends AnyRecord {
myKey1: string;
myKey2: string;
}
// ExtendsAny['myKey'] === string
// ExtendsAny['otherKey'] === any
type OmitsKey = Omit<ExtendsAny, "myKey2">;
// 🚨Problem here 🚨
// OmitsKey['myKey'] === any
// OmitsKey['otherKey'] === any Maybe I'm just being dense here, but you declared two properties |
@RyanCavanaugh Sorry it looks my first example has some typos. The second one (that was linked from the code sandbox was correct.) I've updated my example above and will out it here as well.
The problem is that |
I have similar problem
Line
I believe the code is corrent |
I have this exact problem, and it's kept from compiler from passing for 3 days now. I just realized it's because my top interface extends Record<string, any> (TSC: 3.7.2): interface Item extends Record<string, any> { // problem starts here
id: string
parentId: string
}
interface SubItem extends Item {
foo: string
}
// Omit causes ItemWithOnlyUserAssignableProps to lose its typing for "foo"
interface ItemWithOnlyUserAssignableProps extends Omit<SubItem, 'id' | 'parentId'> {}
// This does not error, and nothing down the line has type-suggestion support in VSCode anymore
const userAssignableItemProps: ItemWithOnlyUserAssignableProps = {
// Missing "foo"
} |
This is such a majorly painful issue. I have this problem (note: in this simple example the problem doesn't occur if it is all laid out in the one file. When importing the types, that is when the types can get lost, possibly only from an npm registry) interface One {
a: string | number
b: string
z: string
}
interface Two {
a: string,
b: string
}
// Error! Named property 'a' of types One and Two are not identical
interface Three extends One, Two {
c: string
}
// So I do this to work around that problem...
interface Three extends Omit<One, 'a'>, Two {
c: string
}
// but then...
const x = (params: Three) => {
params.z // params.z is of the "unknown" type, not of type "string" like it is supposed to be
} |
Ok I finally figured out the real problem behind why Omit was causing me so many headaches. I have a type called interface UnknownProps {
[propName: string]: unknown
} And I was extending my interfaces using it as a way of allowing extra props that were not strictly defined interface ComponentProps extends UnknownProps {
value: string
label: string
} Then when I tried to combine // FilteredProps is of type unknown
type FilteredProps = Omit<ComponentProps, 'label'> Getting rid of This is also a problem for |
@Dan503 Did you figure out a solution that lets you have a type with a couple defined props, and allows any others? This is also being problematic for me as well. |
@douglasg14b I ended up saving the known props into a static interface and then creating a seperate type for using on the component props. export interface StaticComponentProps {
value: string
label: string
}
export type ComponentProps = StaticComponentProps & UnknownProps Then if I want to do something with the component props I target the staticly known type FilteredProps = Omit<StaticComponentProps, 'label'>
// FilteredProps = { value: string } |
TypeScript Version: 3.8 & Nightly
Search Terms:
Expected behavior:
I expect the following types to be as described in the inline comments.
Please note that this works without the omit, or without the record, but not when both are used together.
Actual behavior:
What actually happens is that after using omit, all keys become "any" and any information for code completion, etc that the specifically defined keys even exist, are removed, even thought they were working in the original extension.
Related Issues:
Potential Workaround
In the meantime, I am redefining the base interface (very large) because it comes from a library without the record type mixed in. I do my omit, then add it back in afterwards.
Code
Output
Compiler Options
Playground Link: Provided
The text was updated successfully, but these errors were encountered: