Description
Bug Report
🔎 Search Terms
const
Type Parameters, mapped types, self types
🕗 Version & Regression Information
- This is the behavior in every version I tried, and I reviewed the FAQ for entries about
const
Type Parameters (but there's nothing there about them yet)
⏯ Playground Link
Playground link with relevant code
💻 Code
type WithSchema<Self> = {
// This ensures Self is inferred to be the entire object this type is applied
// to, while the resulting type leaves the *values* of those keys as
// `unknown`.
[K in keyof Self]?: K extends never ? Self[K] : unknown;
} & (("schema" extends keyof Self ? Self["schema"] : {}) extends infer Schema
? {
[K in keyof Schema]?: Schema[K] extends "string"
? string
: Schema[K] extends "number"
? number
: never;
}
: never);
declare function doSomething<const Self>(o: WithSchema<Self>): void;
// doSomething's Self isn't automatically `as const`, despite declaring `const Self`.
doSomething({
schema: {
name: "string",
age: "number",
},
name: "Alice",
age: 35,
});
// Explicitly using `as const` works.
doSomething({
schema: {
name: "string",
age: "number",
},
name: "Alice",
age: 35,
} as const);
🙁 Actual behavior
doSomething
's Self
parameter was not inferred as const
.
🙂 Expected behavior
doSomething
's Self
parameter should be inferred as const
, since it's marked as const
and inferred from a literal at the call site.
More context
I'm actually working on something more complex than this: typing JSON-LD documents. The core of the issue, though, is that the type of some keys of the object depends on another key (here, schema
). I'm doing this using a type parameter which infers as the type of the given object. This uses the same technique described in #52088 (which proposes a more native version using a new keyword).
Currently, the only way to make these types useful is to ask the user of these types to use as const
everywhere. Of course, this is less than ideal, which is exactly why const
Type Parameters were introduced. But it appears the more complex usage I have breaks that feature, reverting to inferring a widened type.