Я описываю все доступные методы для интерфейса с помощью строкового литерального типа объединения.
Затем это используется для описания интерфейса.
Затем я определяю тип возврата любого данного метода из этого интерфейса., который всегда должен быть boolean
.
Каким-то образом TypeScript думает, что это не всегда логическое значение, но я не понимаю, почему и как изменить типизацию, чтобы выразить более четко, что я хочу.
export type method = 'add' | 'get';
export type intfce = { [M in method]: () => boolean };
// => { add: () => boolean; get: () => boolean; }
export type ret<M extends method> = ReturnType<intfce[M]>;
export type retAdd = ret<'add'>; // => boolean
export type retGet = ret<'get'>; // => boolean
export function fn<M extends method>(): ret<M> {
return true; // Error: Type 'true' is not assignable to type 'ReturnType<intfce[M]>'.
}
export function fn2(): boolean {
return true; // OK
}
Я много искал ответы, но, кажется, трудно точно описать, что я пытаюсь сделать, и найти ответ на него.
Мое лучшее предположение, что в случае function fn<M extends method>
M может быть больше, чем просто 'add' | 'get'
.
Итак, я попробовал:
const resAdd = fn<'add'>(); // OK
const resGet = fn<'get'>(); // OK
const resPut = fn<'put'>(); // Error: Type '"put"' does not satisfy the constraint 'method'.
const resToString = fn<'toString'>(); // Error: Type '"toString"' does not satisfy the constraint 'method'.
const resEmpty = fn<''>(); // Error: Type '""' does not satisfy the constraint 'method'.
const resNull = fn<null>(); // Error: Type 'null' does not satisfy the constraint 'method'.
const resUndefined = fn<undefined>(); // Error: Type 'undefined' does not satisfy the constraint 'method'.
const resNumber = fn<0>(); // Error: Type '0' does not satisfy the constraint 'method'.
const resObj = fn<{}>(); // Error: Type '{}' does not satisfy the constraint 'method'.
Полученные ошибки указывают на то, что только 'add' | 'get'
действительно возможны, что возвращает меня к квадрату 1...
Я пытался, если ReturnType
является виновником, и это действительно так, так как код ниже не содержит ошибок:
export type intfce2 = { [M in method]: boolean };
export type ret2<M extends method> = intfce2[M];
export type retAdd2 = ret2<'add'>; // => boolean
export type retGet2 = ret2<'get'>; // => boolean
export function fn3<M extends method>(): ret2<M> {
return true; // Error: Type 'true' is not assignable to type 'ReturnType<intfce[M]>'.
}
Каким может быть ReturnType (повторно-) определено, чтобы заставить работать исходный код?