Skip to content

chore: Migrate with* type tests to TSTyche#9562

Open
MatiPl01 wants to merge 8 commits into
mainfrom
@matipl01/tstyche-with-animations
Open

chore: Migrate with* type tests to TSTyche#9562
MatiPl01 wants to merge 8 commits into
mainfrom
@matipl01/tstyche-with-animations

Conversation

@MatiPl01

Copy link
Copy Markdown
Member

Summary

Continues the TSTyche migration started in #9557 by converting the with* animation __typetests__ and wiring the runner into CI.

  • Migrate withDecay, withTiming, withSpring from @ts-expect-error assertions to TSTyche (.tst.ts):
    • withDecay: DecayConfig validation becomes toBeCallableWith / not.toBeCallableWith.
    • withTiming / withSpring: assert the generic => T contract via toBeAssignableTo, plus a callback-acceptance check.
  • Call type:check:tstyche (scoped to the package) from reanimated's type:check:tests, so the .tst.ts run in CI through the existing command instead of a separate step. worklets stays unwired until it has its first .tst.* test.

Stacked on #9557.

Test plan

  • yarn workspace react-native-reanimated type:check:tests passes (old harness + TSTyche).
  • yarn type:check:tstyche passes.

MatiPl01 and others added 5 commits May 29, 2026 14:51
The __typetests__ suites assert types through tsc failures and ~220
`@ts-expect-error` directives, which match any error on the following line
and give no per-test reporting. Start migrating them to TSTyche, which runs
on the project's own TypeScript and produces named, isolated assertions.

- Add the `tstyche` dev dependency and a `type:check:tstyche` script.
- Add tstyche.config.json scoped to packages/*/__typetests__.
- Convert FeatureFlagTest.tsx to FeatureFlagTest.tst.ts as the first test.
- Make scripts/test-ts.sh skip *.tst.* so the old and new harnesses run
  side by side and files can be migrated one at a time.

Builds on the TSTyche proof of concept from #7727.
Co-authored-by: Tom Mrazauskas <tom@mrazauskas.de>
The 7.2.1 bump could not be installed: the repo's 8-day npm age gate
quarantines it (published 2026-05-27), and the bump left yarn.lock pinned to
4.1.0, which breaks `yarn install --immutable`.

- Add tstyche to npmPreapprovedPackages in .yarnrc.yml.
- Update yarn.lock to TSTyche 7.2.1.
TSTyche v7 changed the default configuration file name from
tstyche.config.json to tstyche.json. Without the rename v7 auto-renames it at
runtime and prints a warning.
@MatiPl01 MatiPl01 self-assigned this May 29, 2026
MatiPl01 added 3 commits May 29, 2026 19:06
CI runs type tests only through each package's `yarn type:check` ->
`type:check:tests`, so the standalone `type:check:tstyche` script left the
.tst.* tests unenforced now that the old harness skips them. Call
`type:check:tstyche`, scoped to the package, from `type:check:tests` so CI
keeps checking them. Scoped by package path to avoid cross-package build
coupling; worklets stays unwired until it has its first .tst.* test.
Convert the withDecay/withTiming/withSpring __typetests__ from
`@ts-expect-error` assertions to TSTyche:

- withDecay: DecayConfig validation becomes toBeCallableWith /
  not.toBeCallableWith.
- withTiming / withSpring: assert the generic `=> T` contract via
  toBeAssignableTo, plus a callback-acceptance check.

Remove the old .tsx files; the new .tst.ts run through type:check:tests.
Rewrite the withTiming and withSpring tests to follow the original
__typetests__ more closely: keep the `useAnimatedStyle` worklet with the
width/backgroundColor style assignments and assert the call type-checks via
`expect(useAnimatedStyle).type.toBeCallableWith(...)`, rather than checking
the animation's return type in isolation.
Comment on lines +8 to +10
expect(useAnimatedStyle).type.toBeCallableWith(() => ({
backgroundColor: withSpring('rgba(255,105,180,0)', {}, (_finished) => {}),
}));

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.

Nice to see the structure in tests.

I only noticed that in these (and in withTiming) tests useAnimatedStyle is passed to expect although the intent is to test the withSpring function. What about something like:

Suggested change
expect(useAnimatedStyle).type.toBeCallableWith(() => ({
backgroundColor: withSpring('rgba(255,105,180,0)', {}, (_finished) => {}),
}));
expect(withSpring('rgba(255,105,180,0)', {}, (_finished) => {})).type.toBe<'rgba(255,105,180,0)'>()

By the way, the original test looks like an integration story. Perhaps it is worth asserting the return type and keeping the rest too:

describe('withSpring', () => {
  test('animates backgroundColor with a color string toValue', () => {
    const backgroundColor = withSpring('rgba(255,105,180,0)', {}, (_finished) => {})

    expect(backgroundColor).type.toBe<'rgba(255,105,180,0)'>()

    const style = useAnimatedStyle(() => {
      return { backgroundColor };
    });

    <View>
      <Animated.View style={style} />
    </View>
  });
});

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Hey! Thanks for your suggestion but I'd actually prefer to test the contract between useAnimatedStyle and the callback function that it is passed instead of testing the withSpring return type directly. Another problem here is that Reanimated uses fake cast of the type returned by withSpring to the same type as the input value, which is not 100% valid as the returned value is, in fact, an object representing an animation. Reanimated needs a huge type refactor in this area so that types represent the actual values but this is something we don't have time for now.

Because of that, I'd rather not test the return type of withSpring directly and keep the compatibility (integration) tests for now, until we refine the internal types.

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.

Ah.. This makes sense. Thanks for the details.

Base automatically changed from @matipl01/typetests-tstyche to main June 10, 2026 18:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants