Skip to content

feat: std.typeOf - #2529

Merged
iwoplaza merged 1 commit into
mainfrom
feat/std-type-of
Oct 20, 2026
Merged

iwoplaza merged 1 commit into
mainfrom
feat/std-type-of

Conversation

@iwoplaza

@iwoplaza iwoplaza commented May 21, 2026 •

Copy link
Copy Markdown
Collaborator

No description provided.

@github-actions

github-actions Bot commented May 21, 2026 •

Copy link
Copy Markdown

pkg.pr.new

packages
Ready to be installed by your favorite package manager ⬇️

https://pkg.pr.new/software-mansion/TypeGPU/typegpu@a0af2518758b1924300ccc379f68dc3131ab54de

benchmark
view benchmark

commit
view commit

@github-actions

github-actions Bot commented May 21, 2026 •

Copy link
Copy Markdown

Bundle size comparison (import * as ... in PR vs import * as ... in target):

🟢 Decreased ➖ Unchanged 🔴 Increased (max 0.96%) ❔ Unknown
0 346 3 3

import * as ... in PR vs import * as ... in target (did bundle size increase?):

Test tsdown
STATIC_std.ts 111.79 kB ($${\color{red}+1.0\%}$$)
d_abstractFloat.ts 20.08 kB
d_abstractInt.ts 20.08 kB
std_typeOf.ts 21.99 kB

If you wish to run a comparison for other, slower bundlers, run the 'Tree-shake test' from the GitHub Actions menu.

@github-actions

github-actions Bot commented May 21, 2026 •

Copy link
Copy Markdown

Resolution Time Benchmark

---
config:
  themeVariables:
    xyChart:
      plotColorPalette: "#E63946, #3B82F6, #059669"
---
xychart
  title "Random Branching (🔴 PR | 🔵 main | 🟢 release)"
  x-axis "max depth" [1, 2, 3, 4, 5, 6, 7, 8]
  y-axis "time (ms)"
  line [0.55, 1.14, 2.26, 3.67, 4.38, 7.62, 13.31, 15.53]
  line [0.50, 1.01, 2.27, 3.55, 4.14, 7.67, 14.00, 14.13]
  line [0.52, 0.99, 2.21, 3.32, 4.12, 6.50, 13.59, 14.92]
Loading
---
config:
  themeVariables:
    xyChart:
      plotColorPalette: "#E63946, #3B82F6, #059669"
---
xychart
  title "Linear Recursion (🔴 PR | 🔵 main | 🟢 release)"
  x-axis "max depth" [1, 2, 3, 4, 5, 6, 7, 8]
  y-axis "time (ms)"
  line [0.14, 0.25, 0.35, 0.41, 0.65, 0.63, 0.75, 0.84]
  line [0.18, 0.31, 0.40, 0.49, 0.71, 0.68, 0.81, 0.89]
  line [0.18, 0.29, 0.40, 0.46, 0.64, 0.56, 0.70, 0.81]
Loading
---
config:
  themeVariables:
    xyChart:
      plotColorPalette: "#E63946, #3B82F6, #059669"
---
xychart
  title "Full Tree (🔴 PR | 🔵 main | 🟢 release)"
  x-axis "max depth" [1, 2, 3, 4, 5, 6, 7, 8]
  y-axis "time (ms)"
  line [0.57, 1.36, 2.20, 4.02, 7.62, 15.44, 31.57, 67.10]
  line [0.44, 1.37, 2.32, 4.46, 6.70, 14.74, 33.16, 63.66]
  line [0.53, 1.27, 2.45, 4.32, 7.33, 14.56, 32.28, 64.12]
Loading

@iwoplaza
iwoplaza force-pushed the feat/std-type-of branch 3 times, most recently from 3dce44a to f60069f Compare October 13, 2026 08:51
@iwoplaza
iwoplaza marked this pull request as ready for review October 13, 2026 08:53
@iwoplaza
iwoplaza requested review from aleksanderkatan, cieplypolar, reczkok and vende11s and a balanced review from Copilot October 13, 2026 08:53

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The matcher can hang for valid regular expressions, and typeOf is not correctly marked or named internally.

3 open findings
What changed in this PR

Adds std.typeOf for compile-time shader type introspection.

Changes:

  • Implements and exports std.typeOf.
  • Adds scalar, assertion, and error-path tests.
  • Adds a reusable match-count matcher.
File Description
packages/​typegpu/​src/​std/​typeOf.ts Implements type introspection.
packages/​typegpu/​src/​std/​index.ts Exports typeOf.
packages/​typegpu/​tests/​std/​typeOf.test.ts Tests the new API.
packages/​typegpu-testing-utility/​src/​index.ts Adds toMatchNTimes.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread packages/typegpu-testing-utility/src/index.ts Outdated
Comment thread packages/typegpu/src/std/typeOf.ts Outdated
Comment thread packages/typegpu/src/std/typeOf.ts

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ No critical issues — two rough edges worth a look.

Reviewed changes

  • New std.typeOf (packages/typegpu/src/std/typeOf.ts): compile-time introspection returning the WGSL type of an expression as a comptime-known value; returns UnknownData for UnknownData/AutoStruct types and throws when called from JS/comptime.
  • std barrel export (packages/typegpu/src/std/index.ts): re-exports typeOf.
  • Tests (packages/typegpu/tests/std/typeOf.test.ts): scalar type resolution, a comptime assertion helper distinguishing f32/i32, and JS/comptime throw behavior.
  • toMatchNTimes matcher (packages/typegpu-testing-utility/src/index.ts): new global vitest matcher plus Matchers type augmentation.

ℹ️ New public API isn't documented

std.typeOf is in the same family as std.isBeingTranspiled / std.getShaderStage / std.getTargetShaderLanguage, which are covered in the "Resolution environment" section of apps/typegpu-docs/src/content/docs/apis/utils.mdx. Adding a short entry there (including the "result can't be stored in a variable" restriction below) would make the new function discoverable and avoid the confusing error new users will otherwise hit.

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

Comment thread packages/typegpu-testing-utility/src/index.ts Outdated
Comment thread packages/typegpu/src/std/typeOf.ts
@iwoplaza
iwoplaza force-pushed the feat/std-type-of branch 2 times, most recently from 5d1bbac to 9c816dc Compare October 14, 2026 16:08

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes

  • Documented std.typeOf in the "Resolution environment" section of apps/typegpu-docs/src/content/docs/apis/utils.mdx, including the "consume immediately / cannot be stored in a variable" restriction.
  • Hardened toMatchNTimes (packages/typegpu-testing-utility/src/index.ts): builds a fresh global regex and counts with matchAll, so a non-global or empty-matching pattern can no longer loop forever and the caller's lastIndex is left untouched.
  • Marked typeOf internal correctly (packages/typegpu/src/std/typeOf.ts): $internal now uses { value: true } so isMarkedInternal recognizes it, the callable registers its name via setName, and the JSDoc documents the no-storage restriction.

All prior review feedback (Copilot's regex-hang, internal-marker, and metadata-naming findings, plus the earlier docs request) is addressed by these commits.

Pullfrog  | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

Comment thread packages/typegpu/tests/std/typeOf.test.ts
Comment thread packages/typegpu-testing-utility/src/index.ts Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't cache array types, so it is currently impossible to compare against them

const inspect = tgpu.comptime((t: unknown) => {
  return tgpu['~unstable'].rawCodeSnippet(`// type = ${t}`, d.Void);
});

test('std.typeof of an arrayExpression', () => {
  const fn = () => {
    'use gpu';
    inspect(std.typeOf([1, 2, 3])).$;
    const t = std.typeOf([1, 2, 3]) === d.arrayOf(d.i32, 3);
  };

  expect(tgpu.resolve([fn])).toMatchInlineSnapshot(`
    "fn fn_1() {
      // type = arrayOf(i32, 3);
      const t = false;
    }"
  `);
});

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's true, though it would be possible if we made deepEqual callable at comptime.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implemented here #3221

Comment thread packages/typegpu/tests/std/typeOf.test.ts
Comment thread packages/typegpu/tests/std/typeOf.test.ts

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes

  • Added std.typeOf tests (packages/typegpu/tests/std/typeOf.test.ts): constant folding (std.typeOf(0) === abstractInt), struct types (std.typeOf(Schema()) === Schema), UnknownData resolution for strings / functions / schema-methods (=== undefined folds to true), and the "assigned to a variable throws" error path.
  • Fixed an occurrences typo in the toMatchNTimes matcher (packages/typegpu-testing-utility/src/index.ts).

The new tests pass locally (pnpm vitest run --project='!browser' packages/typegpu/tests/std/typeOf.test.ts — 7 passed) and oxfmt --check / oxlint --max-warnings=0 are clean on the touched files. These commits respond to the human reviewer's typo and "free tests" requests; the outstanding reviewer threads are informational questions left to that reviewer.

Pullfrog  | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes

  • Narrowed the std.typeOf type filter (packages/typegpu/src/std/typeOf.ts): replaced the type === UnknownData || type instanceof AutoStruct exclusion with the canonical isData(type) predicate, so every internal type (notably EntryInputRouter) now resolves to undefined instead of leaking a non-public schema.
  • Added coverage for internal input types (packages/typegpu/tests/std/typeOf.test.ts): new tests assert std.typeOf of an AutoStruct (render-pipeline fragment input) and of an EntryInputRouter (tgpu.fragmentFn input) both return undefined.

Both prior Pullfrog threads (toMatchNTimes hang, JSDoc storage restriction) remain resolved, and the new commit addresses the human reviewer's internal-leak concern. Tests pass locally (pnpm vitest run --project='!browser' packages/typegpu/tests/std/typeOf.test.ts — 9 passed) and oxfmt --check / oxlint --max-warnings=0 are clean on the touched files.

Pullfrog  | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

Comment thread packages/typegpu-testing-utility/src/index.ts
Comment thread packages/typegpu/src/std/typeOf.ts Outdated
Comment thread packages/typegpu/tests/std/typeOf.test.ts Outdated
Comment thread packages/typegpu/tests/std/typeOf.test.ts Outdated
Comment thread packages/typegpu/tests/std/typeOf.test.ts Outdated
Comment thread packages/typegpu/tests/std/typeOf.test.ts Outdated
Comment thread packages/typegpu/tests/std/typeOf.test.ts Outdated
Comment thread packages/typegpu/tests/std/typeOf.test.ts
@iwoplaza
iwoplaza force-pushed the feat/std-type-of branch 2 times, most recently from 7734bf0 to 2696d6a Compare October 19, 2026 13:32

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

( ◦°^°◦) Arr! I re-checked the fresh commit — the cap'n hoisted d.abstractInt/d.abstractFloat into the public d namespace and swapped the test off its ~internal rope. Typecheck be clean, the nine tests sail true, and CI (treeshake-test included) be green. No new reefs spotted.

Reviewed changes

Since the prior pullfrog review (64b1bf6), the branch was rebased and one authored commit (2696d6a) landed:

  • Made d.abstractInt / d.abstractFloat public (packages/typegpu/src/data/index.ts): added the two numeric schemas and their AbstractInt / AbstractFloat types to the data barrel, so they are reachable through the public d namespace.
  • Switched the constant-folding test to the public API (packages/typegpu/tests/std/typeOf.test.ts): dropped the typegpu/~internal import and compares against d.abstractInt.

npx tsc --noEmit in packages/typegpu is clean, the typeOf suite passes (9 tests), and CI including treeshake-test is green.

Pullfrog  | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ℹ️ No critical issues — one design question inline.

Reviewed changes

Since the prior pullfrog review (2696d6a), a single commit (37f568b) landed, tests only:

  • Added coverage for builtin result structs (packages/typegpu/tests/std/typeOf.test.ts): a new describe block asserting that std.typeOf returns the generated result structs of std.frexp (including the abstract { abstractFloat, abstractInt } case), std.modf, and std.atomicCompareExchangeWeak, with their propTypes; that two same-type results compare === at comptime while frexp vs modf differ; that field access resolves to the field type; and that no struct declaration is emitted.
  • Widened the vitest import to { describe, expect } to support the new block.

The file passes (15 tests), tsc --noEmit is clean, and oxlint/oxfmt report no issues.

🏴☠️ ( ◦°^°◦) Arr! I re-checked the fresh commit — the cap'n stowed a chest o' tests for the builtin result structs, and the whole fleet sails clean. Only one breeze still rustles: the new tests set the opposite course to the review thread that be lyin' open.

Pullfrog  | Fix all ➔ | Fix 👍s ➔ | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

Comment thread packages/typegpu/tests/std/typeOf.test.ts

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes

Since the prior pullfrog review (37f568b), one commit (a0af251) landed, resolving the outstanding maintainer feedback:

  • Swapped the std.typeOf type filter to isWgslData (packages/typegpu/src/std/typeOf.ts): the argument's dataType is now accepted only when isWgslData, matching the reviewer's note that loose schemas cannot appear in shaders. This is the same predicate core/buffer/buffer.ts uses to gate shader-usable schemas, and it still admits the abstract types (d.abstractInt / d.abstractFloat).
  • Narrowed the vitest Matchers augmentation (packages/typegpu-testing-utility/src/index.ts): interface Matchers<T> now matches the shape in vitest's docs, dropping the T = any default and its no-explicit-any suppression. Interface merging with vitest's declaration is still clean under tsc.
  • Normalized test titles (packages/typegpu/tests/std/typeOf.test.ts): std.typeof -> std.typeOf across the affected tests.

🏴☠️ ( ◦°^°◦) Arr! I rigged a fresh look at the new commit — the cap'n swapped the type filter to isWgslData, slimmed the Matchers rigging, and squared the test names. The hold be clean: 15 tests sail true, typecheck and linters show no leaks, and no new reefs spotted.

Pullfrog  | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

@iwoplaza
iwoplaza merged commit 625d30f into main Oct 20, 2026
9 checks passed
@iwoplaza
iwoplaza deleted the feat/std-type-of branch October 20, 2026 12:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants