#typescript #types #callback #typescript-generics
Вопрос:
В TypeScript Playground следующий код гарантирует, что литерал объекта, переданный в createState
, точно соответствует типу State
:
const Stator = {
init: <S>() => {
let s: S;
return {
createState: (state: S): S => {
s = state;
return s;
},
};
},
};
type State = {
status: boolean;
}
const { createState } = Stator.init<State>();
const s = createState({ status: true, fieldIsNotInTypeDeclaration: true });
// ERROR (as expected): Object literal may only specify known properties,
// and 'fieldIsNotInTypeDeclaration' does not exist in type 'State'.
Однако, если я передаю обратный вызов, возвращающий литерал объекта, он проверяет только наличие всех полей типа State
; он не выдает ошибок, если включены дополнительные необъявленные поля:
const Stator = {
init: <S>() => {
let s: S;
return {
createState: (stateInitializer: () => S): S => {
s = stateInitializer();
return s;
},
};
},
};
type State = {
status: boolean;
}
const { createState } = Stator.init<State>();
const s1 = createState(() => ({ status: true, fieldIsNotInTypeDeclaration: true }));
// No error. s1 now includes fieldIsNotInTypeDeclaration,
// despite not being in the State type.
// An error (expected) WILL be generated on attempting to access
// s1.fieldIsNotInTypeDeclaration:
// Property 'fieldIsNotInTypeDeclaration' does not exist
// on type 'State'.
const s2 = createState(() => ({ fieldIsNotInTypeDeclaration: true }));
// ERROR (expected): Property 'status' is missing in type
// '{ fieldIsNotInTypeDeclaration: boolean; }' but required in type 'State'.
Я понимаю, что это можно улучшить, введя прямой обратный вызов:
const s3 = createState((): State => ({ fieldIsNotInTypeDeclaration: true }));
// ERROR (expected): Object literal may only specify known properties,
// and 'fieldIsNotInTypeDeclaration' does not exist in type 'State'.
… но разве я не должен был этого делать? State
был передан .init
как универсальный, и createState
то, что он вернул, уже имеет этот тип. Это подтверждается наведением курсора:
[
Я чего-то не понимаю?
Комментарии:
1. Typescript применяет проверки избыточных свойств только при назначении литералов. Это их дизайнерский выбор. Поищите «проверки избыточных свойств машинописного текста», и вы найдете множество блогов об этом.