I wrote a fairly straightforward mapped-types based code, which doesn't want to type check for some reason.
First, define input and output:
interface Validated<T> {
valid: boolean;
value: T;
}
interface FieldInputs {
name: string;
price: number;
}
interface ParsedFields {
name: Validated<string>;
price: Validated<number>;
}
Define parser types and parser map:
type FieldKey = keyof FieldInputs & keyof ParsedFields;
type FieldParser<F extends FieldKey> = (value?: FieldInputs[F]) => ParsedFields[F];
type FieldParsers = {
[F in FieldKey]: FieldParser<F>;
};
declare let fieldParsers: FieldParsers;
Now this very simple generic function fails to type-check:
function update<F extends FieldKey>(field: F, value: FieldInputs[F]) {
const parser: FieldParser<F> = fieldParsers[field];
parser.apply(value);
}
gives the following error (--strictFunctionTypes
):
Type 'FieldParsers[F]' is not assignable to type 'FieldParser<F>'.
Type 'FieldParser<"name"> | FieldParser<"price">' is not assignable to type 'FieldParser<F>'.
Type 'FieldParser<"name">' is not assignable to type 'FieldParser<F>'.
Types of parameters 'value' and 'value' are incompatible.
Type 'FieldInputs[F]' is not assignable to type 'string'.
Type 'string | number' is not assignable to type 'string'.
Type 'number' is not assignable to type 'string'.
What am I missing?