Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Sep 20, 2025

Problem

Users were unable to pass readonly arrays and objects as constraint parameters without encountering TypeScript compilation errors. This created friction for codebases that prefer readonly data structures for better immutability guarantees.

Consider this common scenario:

// ❌ Previously caused TypeScript errors
const readonlyValues: readonly Arbitrary<unknown>[] = [fc.boolean(), fc.integer()];
fc.object({ values: readonlyValues }); // Type error!

const readonlySchemes: readonly string[] = ['http', 'https'] as const;
fc.webUrl({ validSchemes: readonlySchemes }); // Type error!

Solution

Updated constraint interfaces to accept readonly arrays while maintaining full backward compatibility:

  • ObjectConstraints.values now accepts readonly Arbitrary<unknown>[]
  • WebUrlConstraints.validSchemes now accepts readonly string[]
  • ArrayConstraintsInternal.experimentalCustomSlices now accepts readonly (readonly T[])[]

The implementation leverages TypeScript's contravariance rules where functions accepting readonly T[] can also accept T[], ensuring existing code continues to work unchanged.

After this change

// ✅ Now works perfectly!
const readonlyValues: readonly Arbitrary<unknown>[] = [fc.boolean(), fc.integer()];
fc.object({ values: readonlyValues }); // No errors ✅

const readonlySchemes: readonly string[] = ['http', 'https'] as const;
fc.webUrl({ validSchemes: readonlySchemes }); // No errors ✅

// ✅ Existing mutable arrays still work (backward compatibility)
const mutableValues = [fc.boolean(), fc.integer()];
fc.object({ values: mutableValues }); // Still works ✅

Technical Details

  • Updated internal helper functions to safely handle readonly arrays using spread operator when conversion to mutable arrays is needed
  • Modified the entire constraint processing pipeline from interfaces down to implementation classes
  • Added comprehensive tests demonstrating readonly constraint functionality
  • Ensured no runtime behavior changes - this is purely a TypeScript typing improvement

This change makes fast-check more compatible with modern TypeScript codebases that prefer readonly data structures while maintaining complete backward compatibility.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

@changeset-bot
Copy link

changeset-bot bot commented Sep 20, 2025

⚠️ No Changeset found

Latest commit: 52e780b

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copilot AI changed the title [WIP] Add read-only annotations to typings of the types xConstraints when relevant. Users should be allowed to pass read-only fields and options when legit Add readonly support to constraint interfaces for better TypeScript compatibility Sep 20, 2025
Copilot AI requested a review from dubzzz September 20, 2025 08:12
Copilot finished work on behalf of dubzzz September 20, 2025 08:12
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.

2 participants