Typescript иногда применяет строгую проверку свойств, а иногда нет. Когда применяется двоеточие, всегда применяется строгая проверка свойств (за исключением аргументов функции). Когда двоеточие не применяется, сравнивается структура, чтобы увидеть, соответствует ли структура псевдонима, если true, типы совместимы, и это является ядром структурной типизации. Эта проверка двоеточия применяется к ближайшему двоеточию в области.
IStore или Partial, если для ReturnType применяется двоеточие, может иметь только {test: string} или {}; но никогда не лишние свойства.
* 1003 то есть *
const foo2 = (): Partial<IStore> => ({}); // is allowed but...
const foo2 = (): Partial<IStore> => ({notALlowed: true}); // not allowed
Когда двоеточие не применяется, оно выполняет структурную проверку типа с избыточным свойством off, это случай псевдонима типа для функции.
type IFunction<S> = (store: S) => Partial<S>;
const foo1: IFunction<IStore> = () => ({
test: '',
test2: '' // why no errors in this row?
});
Теперь может возникнуть некоторая путаница, потому что оба фрагмента реализуют двоеточие, но различие заключается в том, где двоеточие расположено, в случае функций двоеточие слева будет применять только строгую проверку свойств для аргументов функции, но никогда ReturnType.