Currently, I am in the process of familiarizing myself with Typescript through its application in a validation library that I am constructing.
types.ts
export type Value = string | boolean | number | null | undefined;
export type ExceptionResult = {
__errorType: string;
__errorArgs: string[];
};
export type ValidationResult =
| [ExceptionResult]
| [undefined, Value]
| undefined;
export type Rules = {
always: (defaultValue: Value) => (value: Value) => ValidationResult;
[key: string]: (defaultValue: Value) => (value: Value) => ValidationResult;
};
String.ts
type ValueAlways = Extract<Value, string | undefined | null>;
type ValueOther = Extract<Value, string>;
export const rules: Rules = {
always: (defaultValue: ValueAlways) => (value: ValueOther) => {
if (defaultValue !== undefined && (value == null || defaultValue === value))
return [undefined, defaultValue];
if (typeof value !== "string" || value === "")
return [Exception("String", [])];
},
equal: (mustBe: ValueOther) => (value: ValueOther) => {
if (mustBe !== value) return [Exception("StringEqual", [mustBe])];
},
}
Error message
Type '(defaultValue: ValueAll) => (value: ValueSpec) => [undefined, string | null] | [ExceptionResult] | undefined' is not assignable to type '(defaultValue: Value) => (value: Value) => ValidationResult'.
Types of parameters 'defaultValue' and 'defaultValue' are incompatible.
Type 'Value' is not assignable to type 'string | null | undefined'.
Type 'number' is not assignable to type 'string | null | undefined'.ts(2322)
types.ts(9, 2): The expected type comes from property 'always' which is declared here on type 'Rules'
The concept behind my approach was to define a Value
type that encompasses all supported types, along with ValueAlways
and ValueOther
types for specific type restrictions. Despite this, there seems to be an issue with compatibility between Value, ValueAlways, and ValueOther.
Why does this error occur? And why does it specifically mention the 'number' type?