-
Notifications
You must be signed in to change notification settings - Fork 12.8k
[nightly][regression] Mapped type over generic key unexpectedly makes key treated as optional #57860
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
Comments
This is likely the same thing that I've raised here. type requiredKeys<T extends object> = {
[k in keyof T]: undefined extends T[k] ? never : k;
}[keyof T];
export type addQuestionMarks<
T extends object,
R extends keyof T = requiredKeys<T>
> = Pick<Required<T>, R> & Partial<T>; So their definitions always contain a possibility of an optional property. This type is not generic though and the fact that its origin is in this mapped type is something that the user doesn't really ever see so it's a surprising behavior. |
We'd need a standalone repro (i.e. one that doesn't import anything, certainly not something as complex as zod) here to investigate further |
@RyanCavanaugh I could try to boil down Zod's case to the bare minimum but from what I understand the underlying root cause for this in Zod is the same as in the comment I've quoted. Copying the mentioned code there (TS playground): type Obj = {
a: string;
b: number;
};
type Obj2 = {
b: number;
c: boolean;
};
declare const mapped: {
[K in keyof (Partial<Obj> & Required<Obj2>)]: number;
};
// displays the same way as `resolved` below!
mapped;
// ^? const mapped: { a?: number | undefined; b: number; c: number; }
const accessMapped = <K extends keyof Obj2>(key: K) => mapped[key].toString(); // error, a mystery to the user
declare const resolved: { a?: number | undefined; b: number; c: number };
const accessResolved = <K extends keyof Obj2>(key: K) => resolved[key].toString(); // since this is OK |
Above example bisects to the same PR, to be clear |
@Andarist beat me to it, but I reduced it down to this, which I think more strongly shows that something is wrong type EmptyObject = {[K in never]?: never}; // This is just `{}` ?
type BadData = { id: string, prop: string } & EmptyObject;
function badExample<K extends keyof BadData>(data: Pick<Pick<BadData, K | 'id'>, K>): Pick<BadData, K> {
return data;
// ^^^^Same error
} |
Even simpler repro: type Foo = {
prop: string;
}
function test<K extends keyof Foo>(obj: Pick<Required<Foo> & Partial<Foo>, K>, key: K) {
obj[key].length; // Error: Object is possibly 'undefined'
} |
π Search Terms
regression mapped type generic intersection undefined optional
π Version & Regression Information
β― Playground Link
https://www.staging-typescript.org/play?ts=5.5.0-dev.20240319#code/JYWwDg9gTgLgBAbwF4F84DMoRHA5EiAE1wG4BYAKEsoGMIA7AZ3kZoAsBTEAQzgF44SAHQQARgCsONGAAoElOIrhgsYAFyChzKMHoBzGQEoANJRSHyVK-IpK4MAJ5gOcACIcdANw6EAKk5cBYV10DwAeR2cIdDhWTh4APksFJUiXACFuQlduGF4BBDhgQg1tXT04NAAyNw9gbz8A5NsldABXemlgBjhRLIBRAA9ucAAbDjCAaTgOQZgOekJGOABrDgdouEzs3O4EmUJdjQAFYBoVsNPzsO2cvOM4aYAfPGLcBIfJhMMTs4vb3afBKIFJ2RRQDgwNpQehwQ55Sx2AD0SMUAD0MZi4P5nHgrhd8WE7txPnAXgAiYrkj6PBK4IrLegQeDcRiMYB6ejcUTjewQewBPF-ImA2m4ISguAosEynEuXDEgDaxwAumS4B1CBx0LofPTgIzmXBWezOdzeTB+Wk8ErVeLJdKZbLBbhNdrdcQGXAmSy2RyuTyXJaBbiFbtlSr7S1FI6nc7Q26dfQ9V6fca-WbA3yQ-KyvpxTIAEwAZkLhcMdklKDM1AoNjs1qGYFGZ2AMDl-BB0bBKgg6liMB0+kRSmrVgbgoA4hAiMTO4ViqVB+VKnAak2WzQ23LmnZ2p0YN1YXoZ4QhiNmxNprN5otlmsNjFp7Pdvt4dxftdCc+dvdHurcDeGkvh+OBv1PYkgS7OMIShGE4V2EdFDHFAgA
π» Code
π Actual behavior
Type error
π Expected behavior
No type error.
DerivedType
expands toExplicitType
, yet produces different results.Additional information about the issue
The title of this issue is probably inaccurate/misleading. I just wasn't sure how to describe the behavior. Note that I discovered this while using Airtable's internal schema lib, yet fortunately I was also able to reproduce this with Zod despite the implementations of the
infer
type being entirely different.I bisected this to this commit 3b1b82a with @ahejlsberg's PR #57549
The text was updated successfully, but these errors were encountered: