typespec1-8 Exercise 2: Fixing Lint Warnings and Failing the Build ========================================================================= lint.tsp (the chapter's file; the three rules are enabled in tspconfig_lint_strict.yaml, which also has warn-as-error: true): import "@typespec/http"; import "@typespec/versioning"; using Http; using TypeSpec.Versioning; @service(#{ title: "Lint Demo" }) namespace LintDemo; model Book { id: string; } model Wrapper { value: T; } @route("/shared") interface Shared { @get ping(): string; } interface Mine { ping is Shared.ping; } @route("/books") interface Books { @get list(): Wrapper; } Before: the three warnings (shown in the chapter) and exit code 1 with warn-as-error. FIX 1 AND 2 (easy): delete 'import "@typespec/versioning"' and 'using TypeSpec.Versioning;', and delete the unused template parameter (Wrapper becomes Wrapper, and its use becomes Wrapper). FIX 3 (my first attempt was wrong). I thought the problem was the missing prefix, so I put @route("/shared") on Mine as well as on Shared. The compiler then reported a genuine error, which is worse than the warning: Diagnostics were reported during compilation: lintfix.tsp:14:8 - error @typespec/http/duplicate-operation: Duplicate operation "ping" routed at "get /shared". > 14 | @get ping(): string; | ^^^^ lintfix.tsp:19:3 - error @typespec/http/duplicate-operation: Duplicate operation "ping" routed at "get /shared". > 19 | ping is Shared.ping; | ^^^^ Found 2 errors. Two operations on the same verb and path. My second attempt used a different prefix, @route("/mine") on Mine. The lint rule still fired: lintfix.tsp:19:3 - error @typespec/http/op-reference-container-route: Operation ping references an operation which has a @route prefix on its namespace or interface: "/shared". ... (it is an 'error' in that run only because warn-as-error turns warnings into errors.) The rule is not about whether the copy has a route: it fires whenever the ORIGINAL's route is on its container. The third attempt moved the route from Shared's interface to the operation itself, which is carried with 'is': import "@typespec/http"; using Http; @service(#{ title: "Lint Demo" }) namespace LintDemo; model Book { id: string; } model Wrapper { value: T; } interface Shared { @route("/shared") @get ping(): string; } @route("/mine") interface Mine { ping is Shared.ping; } @route("/books") interface Books { @get list(): Wrapper; } Compiled with the strict config: 'Compilation completed successfully.', exit code 0. The resulting paths, from the OpenAPI output: /books, /mine/shared and /shared. Mine.ping got the prefix of its own interface plus the route that came with the operation. WHY THIS WORKS AS AN ANSWER --------------------------- The first two fixes are mechanical. The third shows why the rule exists: the two obvious repairs for a lint warning (copy the route, give a different route) either break the API or leave the warning. Keeping the route on the operation, where 'is' carries it, is what the rule is pushing you toward.