fix(cli): close the extra-field gap in AssertAssignable, add tsc-based enforcement tests
AssertAssignable was one-directional ([Actual] extends [Expected]), so a block declaring a field the contract doesn't accept passed silently (TypeScript's excess-property check only applies to fresh object literals, not conditional-type extends). Add a key-exactness check (Exclude<keyof Actual, keyof Expected> extends never) alongside the assignability check. Guard it with 'unknown extends Expected' so untyped (no defineEndpoint contract) routes still only warn, per the existing behaviour, instead of being forced to fail on every declared field. Add packages/cli/test/api-block-types.test.ts cases that regenerate a fixture and run the real TypeScript compiler (via bunx tsc) over the generated output, asserting on its diagnostics rather than on emitted text: matching fields compile clean; a wrong-typed field, an extra field (the Finding-A regression guard), and a missing required field all fail, each pointing at the offending block's __wrn_api_check_* line. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+7
-1
@@ -57,7 +57,13 @@ declare namespace WRNexusGenerated {
|
||||
"welcome-email": QueuePayload<(typeof import("../queues/welcome-email.ts"))["default"]>;
|
||||
}
|
||||
type ApplicationConfig = (typeof import("../../wrnexus.config.ts"))["default"];
|
||||
type AssertAssignable<Actual, Expected> = [Actual] extends [Expected] ? true : false;
|
||||
type AssertAssignable<Actual, Expected> = unknown extends Expected
|
||||
? true
|
||||
: [Actual] extends [Expected]
|
||||
? [Exclude<keyof Actual, keyof Expected>] extends [never]
|
||||
? true
|
||||
: false
|
||||
: false;
|
||||
type __wrn_expect_true<T extends true> = T;
|
||||
type ApiInput<P extends ApiRoute, M> = ApiContracts[P][M]["input"];
|
||||
type ApiOutput<P extends ApiRoute, M> = ApiContracts[P][M]["output"];
|
||||
|
||||
Reference in New Issue
Block a user