Description
🔎 Search Terms
inference, deeply nested, no error, type evaluation, typebox, hkt
🕗 Version & Regression Information
Hi,
I've come across some unusual behavior where TypeScript seems to be skipping checks for certain kinds of computed types. This seems to be specific to deeply nested object types that are computed via intersection. I note that the language service is reporting the correct type information in editor, however the compiler seems to be skipping checks on the reported type. This behavior can be observed using the TypeBox library, specifically for object types at least 2 levels deep.
- This is the behavior in every version I tried (5.1.6 onwards)
⏯ Playground Link
💻 Code
import { Static, Type } from "@sinclair/typebox"
export type Input = Static<typeof Input>
export const Input = Type.Object({
level1: Type.Object({
level2: Type.Object({
foo: Type.String(),
})
})
})
export type Output = Static<typeof Output>
export const Output = Type.Object({
level1: Type.Object({
level2: Type.Object({
foo: Type.String(),
bar: Type.String(),
})
})
})
// The following functions should all report errors for the return value, however the first does not.
function problematicFunction1(ors: Input[]): Output[] {
return ors; // <-- this does not error
}
function problematicFunction2<T extends Output[]>(ors: Input[]): T {
return ors; // <-- ... but this does
}
function problematicFunction3(ors: (typeof Input.static)[]): Output[] {
return ors; // <-- ... and so does this
}
🙁 Actual behavior
First function does not report an error
🙂 Expected behavior
All functions should report errors
Additional information about the issue
I get the feeling this may have something to do with TypeBox's implementation of Static<T>
and where TypeScript may be implementing some optimizations around certain forms of computed / evaluated types (but not sure). TypeBox currently implements Static<T>
as follows.
type Static<T extends TSchema, P extends unknown[] = []> = (T & { params: P; })["static"]
By removing the intersection of P, TypeScript correctly asserts the problematicFunction1
return type.
type Static<T extends TSchema, P extends unknown[] = []> = T["static"] // this is fine