You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
<Admonitiontype="info"title="Type System Escape Hatches">
352
+
353
+
The `narrow`, `assert`, `defined`, and `cast` methods serve as escape hatches for current TypeScript limitations with lens type compatibility. These methods address scenarios where you need to pass lenses with wider types to components expecting narrower types.
354
+
355
+
These workarounds will become less necessary once [issue #38](https://github.com/react-hook-form/lenses/issues/38) is resolved, which aims to improve lens type variance to allow more natural type narrowing and component composition.
356
+
357
+
</Admonition>
358
+
359
+
### narrow {#narrow}
360
+
361
+
The `narrow` method provides type-safe narrowing of union types, allowing you to tell the type system which branch of a union you want to work with. This is particularly useful when working with discriminated unions or optional values.
362
+
363
+
#### Manual Type Narrowing
364
+
365
+
Use the single generic parameter to manually narrow the type when you know (by external logic) what the value should be:
366
+
367
+
```tsx copy
368
+
// Lens<string | number>
369
+
const unionLens =lens.focus("optionalField")
370
+
371
+
// Narrow to string when you know it's a string
372
+
const stringLens =unionLens.narrow<string>()
373
+
// Now: Lens<string>
374
+
```
375
+
376
+
#### Discriminated Union Narrowing
377
+
378
+
Use the discriminant overload to narrow based on a specific property value:
The `narrow` method performs type-level operations only. It doesn't validate the runtime value - use it when you have external guarantees about the value's type (e.g., from validation, conditional rendering, or runtime checks).
396
+
397
+
</Admonition>
398
+
399
+
### assert {#assert}
400
+
401
+
The `assert` method provides runtime type assertions that convince TypeScript the current lens is already the desired subtype. Unlike `narrow`, this is a type assertion that modifies the current lens instance.
402
+
403
+
#### Manual Type Assertion
404
+
405
+
Use the generic parameter to assert the lens is already the desired type:
`assert` is a type-only operation that doesn't perform runtime validation. Ensure your assertions are backed by proper runtime checks to avoid type safety violations.
444
+
445
+
</Admonition>
446
+
447
+
### defined {#defined}
448
+
449
+
The `defined` method is a convenience function that narrows the lens type to exclude `null` and `undefined` values. This is equivalent to using `narrow<NonNullable<T>>()` but provides a more expressive API.
The `cast` method forcefully changes the lens type to a new type, regardless of compatibility with the original type. This is a powerful but potentially **unsafe** operation that should be used with extreme caution.
<Admonitiontype="danger"title="Use with Extreme Caution">
533
+
534
+
`cast` bypasses TypeScript's type system entirely. It can lead to runtime errors if the underlying data doesn't match the asserted type. Always validate data at runtime before using `cast`, or prefer safer alternatives like `narrow` when possible.
You can extend the basic lens functionality by adding custom methods to the `LensBase` interface. This is useful when you need additional methods that aren't available in the default lens API.
802
+
803
+
For example, let's add a `getValue` method to the lens that allows you to easily retrieve the current form values.
804
+
805
+
**Step 1: Create the type declarations file**
806
+
807
+
Create a `lenses.d.ts` file to extend the basic interface with the methods you want:
808
+
809
+
```typescript
810
+
declaremodule"@hookform/lenses" {
811
+
interfaceLensBase<T> {
812
+
getValue():T
813
+
}
814
+
}
815
+
816
+
export {}
817
+
```
818
+
819
+
**Step 2: Create the custom lens core implementation**
820
+
821
+
Create a `MyLensCore.ts` file with the actual runtime implementation:
Now you can use this hook as usual and you have the new method with correct TypeScript support:
865
+
866
+
```typescript
867
+
const lens =useMyLens(form)
868
+
lens.getValue() // Your custom method is now available with full type support
869
+
```
870
+
871
+
This pattern allows you to add any custom functionality to lenses while maintaining full type safety and compatibility with the existing lens API.
872
+
608
873
<Admonitiontype="tip"title="Questions or Feedback?">
609
874
610
875
Found a bug or have a feature request? Check out the [GitHub repository](https://github.com/react-hook-form/lenses) to report issues or contribute to the project.
0 commit comments