String extension documentation
This page documents the explicit String extension path. For ordinary application code, prefer schema-dsl/pure + s. Use this page when you intentionally want direct string-chain authoring, or when you need to maintain compatibility with code that already uses it.
Core features
After explicitly enabling String extensions, strings can directly call chain methods
Advantages:
- ✅ More concise and natural
- ✅ Reduce the amount of code
- ✅ Can coexist with
s('...')seeds ands.xxx()factories
Default alternative: no prototype mutation
If you do not want to modify String.prototype, import from schema-dsl/pure and use s('...') or s.xxx() factories from the start:
Side-effect-controlled entries
The root schema-dsl entry still installs String extensions for v1 compatibility. New code should usually start from schema-dsl/pure; use the explicit entries below only when you intentionally want direct string-chain authoring.
For builds that want String-chain authoring without runtime prototype mutation, use transformSchemaDsl() or schemaDslEsbuildPlugin() to rewrite static chains into s('...') calls that import from schema-dsl/pure. The default transform covers the full built-in String extension method set and naked pipe enums; add user-defined methods with additionalMethods, and add registered custom DSL type literals with additionalTypes or additionalTypePatterns.
Available direct String methods
The following methods are installed on String.prototype by the root entry or schema-dsl/register-string. This list mirrors the runtime STRING_EXTENSION_METHODS list. DslBuilder.length(n) and DslBuilder.trim() are intentionally not installed because JavaScript strings already have native .length and .trim() members.
Examples:
quick start
Detailed example
The following examples assume direct String extensions have been explicitly registered. If you do not want runtime prototype mutation, use s('...') or s.xxx() instead.
1. Regularity validation
Correct error code:
'required'- required field'min'- minimum length/value'max'- maximum length/value'pattern'- Regular validation'format'- Format validation (email/url, etc.)'enum'- enumeration value
2. Customize error messages
Message template variables:
{{#label}}- field label{{#limit}}- constraint value (min/max){{#value}}- current value{{#pattern}}- regular expression
3. Custom validator
⚠️ .custom() supports synchronous functions; when asynchronous library checking or remote calling is required, you can return Promise and use validateAsync(). Synchronous validate() will return an explicit error when encountering a Promise-returning custom validator.
Supported return values:
- Do not return/
undefined→ Validation passed ✅ - return string → validation failed (error message)
- Return
{ error, message }→ Custom error code - throw exception → validation failed
- Return
true→ Validation passed - Return
false→ Authentication failed (default message)
Notice:
- The current version supports returning
Promisein.custom(), but must be performed throughvalidateAsync(). - If you want to leave the database/RPC/HTTP check in the business layer, you can also use
schema-dslto do structure validation first, and then perform asynchronous checking in the business layer.
5. Default validator
username default:
'short'- 2-16'medium'- 3-32 (default)'long'- 5-64'3-32'- Custom scope
phone supported countries:
'cn'- China (11th place)'us'- United States'uk'- United Kingdom
password strength:
'weak'- 6-64'medium'- 8-64 (default)'strong'- 8-64 (uppercase and lowercase + numbers)
6. Complete form example
Multi-language support
Solution 1: Global multi-language configuration (recommended)
Option 2: Field-level multilingualism
Option 3: Dynamic switching at runtime
Recommended solution: Solution 1 (global configuration) + Solution 2 (special field coverage)
Compatibility installation and cleanup
Compatibility installation
The root compatibility entry and schema-dsl/compat install String extensions on import. New code should prefer schema-dsl/pure unless direct String chains are intentional.
The extension is mounted to String.prototype with non-enumerable attributes, and detects external methods with the same name during installation; if it is found that the method is not installed by schema-dsl itself, it will refuse to overwrite it.
If your running environment has extended a method with the same name (such as String.prototype.label) before importing schema-dsl, the root entry will throw a conflict error during the import phase to avoid silently overwriting the external implementation. The solution is to first remove or rename the conflicting external extension, and then import schema-dsl; ordinary projects usually do not encounter this scenario.
Disable after an explicit install
Re-enable or customize the installation
best practices
1. Use pure DSL for simple fields
2. Use chain calls for complex fields
3. Follow the 80/20 rule
Use pure DSL strings for simple fields. Use direct string chains only when that authoring style is intentional; otherwise use s('...') for explicit DSL seeds with builder hints or s.xxx() factories for the strongest method discovery. In TypeScript, direct string chain hints require schema-dsl/string-types.
FAQ
Q1: Will String expansion pollute the global situation?
A: Direct String chains modify String.prototype, so they are opt-in for new code. For no import-time prototype mutation, import from schema-dsl/pure and use s('...') or s.xxx(). When you intentionally want direct string chains, import schema-dsl/register-string during application startup. uninstallStringExtensions() is mainly for test cleanup or legacy compatibility checks.
Q2: How is the performance?
A: Treat String extension overhead as an ergonomics concern rather than a permanent performance claim. For hot paths, reuse schema objects and validators, then verify with the benchmark route described in Performance Optimization Guide.
Q3: Is TypeScript supported?
A: Fully supported. Use s('...') or s.xxx() for the default no-global-type path, or import schema-dsl/string-types when a TypeScript project intentionally wants String-chain IDE hints for code that is compiled through the transform.
Q4: What is the correct error code?
A:
'required'- required'min'/'max'- length/value range'pattern'- Regular'format'- format (email/url)'enum'- enumeration
Q5: How to support multiple languages?
A: Use Locale global configuration (recommended) or field-level .messages() override.
Related documents
Corresponding sample file
Example entry: string-extensions.ts
Description: Covers the installation/uninstallation of String.prototype extension, chained .label() / .messages() / .pattern() calls, and validation success/failure paths.