From a745145226599040af5832111848d4a5fcc45510 Mon Sep 17 00:00:00 2001 From: Jason Bedard Date: Fri, 28 Aug 2026 13:50:55 -0700 Subject: [PATCH] fix: emit source dts files in ts_project output --- examples/dts_srcs/BUILD.bazel | 65 ++++++++++++++++++++++++++++++++ examples/dts_srcs/index.ts | 2 + examples/dts_srcs/src/index.ts | 2 + examples/dts_srcs/src/types.d.ts | 1 + examples/dts_srcs/tsconfig.json | 5 +++ examples/dts_srcs/types.d.ts | 1 + ts/private/ts_project.bzl | 9 +++-- 7 files changed, 82 insertions(+), 3 deletions(-) create mode 100644 examples/dts_srcs/BUILD.bazel create mode 100644 examples/dts_srcs/index.ts create mode 100644 examples/dts_srcs/src/index.ts create mode 100644 examples/dts_srcs/src/types.d.ts create mode 100644 examples/dts_srcs/tsconfig.json create mode 100644 examples/dts_srcs/types.d.ts diff --git a/examples/dts_srcs/BUILD.bazel b/examples/dts_srcs/BUILD.bazel new file mode 100644 index 00000000..ce5aa8b9 --- /dev/null +++ b/examples/dts_srcs/BUILD.bazel @@ -0,0 +1,65 @@ +"""ts_project(srcs) containing .d.ts files with various outDir/rootDir settings. + +A .d.ts src is never transpiled or relocated by tsc, so it is passed through to +JsInfo(types) (the `types` output group) at its source location. +""" + +load("@aspect_rules_ts//ts:defs.bzl", "ts_project") +load("@bazel_lib//lib:testing.bzl", "assert_outputs") + +ts_project( + name = "default", + srcs = [ + "index.ts", + "types.d.ts", + ], + declaration = True, +) + +assert_outputs( + name = "default_types_test", + actual = ":default_types", + expected = [ + "dts_srcs/index.d.ts", + "dts_srcs/types.d.ts", + ], +) + +ts_project( + name = "out_dir", + srcs = [ + "index.ts", + "types.d.ts", + ], + declaration = True, + out_dir = "dist", +) + +assert_outputs( + name = "out_dir_types_test", + actual = ":out_dir_types", + expected = [ + "dts_srcs/dist/index.d.ts", + "dts_srcs/types.d.ts", + ], +) + +ts_project( + name = "root_dir_out_dir", + srcs = [ + "src/index.ts", + "src/types.d.ts", + ], + declaration = True, + out_dir = "dist2", + root_dir = "src", +) + +assert_outputs( + name = "root_dir_out_dir_types_test", + actual = ":root_dir_out_dir_types", + expected = [ + "dts_srcs/dist2/index.d.ts", + "dts_srcs/src/types.d.ts", + ], +) diff --git a/examples/dts_srcs/index.ts b/examples/dts_srcs/index.ts new file mode 100644 index 00000000..f4ba7ec6 --- /dev/null +++ b/examples/dts_srcs/index.ts @@ -0,0 +1,2 @@ +export * from './types' +export const value = 1 diff --git a/examples/dts_srcs/src/index.ts b/examples/dts_srcs/src/index.ts new file mode 100644 index 00000000..f4ba7ec6 --- /dev/null +++ b/examples/dts_srcs/src/index.ts @@ -0,0 +1,2 @@ +export * from './types' +export const value = 1 diff --git a/examples/dts_srcs/src/types.d.ts b/examples/dts_srcs/src/types.d.ts new file mode 100644 index 00000000..932546d8 --- /dev/null +++ b/examples/dts_srcs/src/types.d.ts @@ -0,0 +1 @@ +export type A = number diff --git a/examples/dts_srcs/tsconfig.json b/examples/dts_srcs/tsconfig.json new file mode 100644 index 00000000..d5f8d1fb --- /dev/null +++ b/examples/dts_srcs/tsconfig.json @@ -0,0 +1,5 @@ +{ + "compilerOptions": { + "declaration": true + } +} diff --git a/examples/dts_srcs/types.d.ts b/examples/dts_srcs/types.d.ts new file mode 100644 index 00000000..932546d8 --- /dev/null +++ b/examples/dts_srcs/types.d.ts @@ -0,0 +1 @@ +export type A = number diff --git a/ts/private/ts_project.bzl b/ts/private/ts_project.bzl index 3b22560b..f9b6d6dc 100644 --- a/ts/private/ts_project.bzl +++ b/ts/private/ts_project.bzl @@ -233,7 +233,7 @@ See https://github.com/aspect-build/rules_ts/issues/361 for more details. # # Unfortunately this duplicates logic in ts_lib.calculate_outs: # files collide iff the following conditions are met: - # - They are files not renamed when transpiled (ext in [.d.ts, js, json]) + # - They are files not renamed when transpiled (ext in [js, json]) # - out_dir == root_dir # # The duplication is hard to avoid, since calculate_outs works on path strings @@ -242,8 +242,11 @@ See https://github.com/aspect-build/rules_ts/issues/361 for more details. for s in srcs_inputs: if _lib.is_js_src(s.path, ctx.attr.allow_js, ctx.attr.resolve_json_module): output_sources.append(s) - if _lib.is_typings_src(s.path): - output_types.append(s) + + # Add .d.ts inputs which are never emitted by tsc. + for s in srcs_inputs: + if _lib.is_typings_src(s.path): + output_types.append(s) is_root_module = ctx.label.workspace_root == ""