При использовании композиционного подхода в машинописи над наследованием один я хочу описать свои сущности в соответствии с тем, что они «могут», а не с тем, что они «есть». Чтобы сделать это, мне нужно создать несколько сложных интерфейсов, а затем для своих классов (я использую классы, чтобы не создавать цепочку прототипов вручную и не нарушать некоторые оптимизации, которые, как я предполагаю, существуют внутри движков js) для реализации моих интерфейсов. Но это приводит к странному поведению, когда тип метода не определен правильно. Наоборот, при использовании объектов и объявлении их одинакового типа интерфейса все работает как положено.
Так что я использую VSCode с машинописью 3.6.3. Я создал интерфейс для 2D-фигуры, который должен иметь метод для возврата всех нормалей к краям. Затем я создаю класс, который реализует этот интерфейс, и я ожидаю, что он потребует этот метод, и он должен иметь тот же тип возвращаемого значения (эта часть работает), а также те же типы аргументов (этот не имеет). Параметр выводится как любой. Моя проблема в том, что я не хочу создавать цепочку прототипов вручную, чтобы получить согласованное поведение VSCode.
Также при запуске tsc в консоли я получаю ту же ошибку для параметра «любой» тип в методе класса и ожидаемую ошибку в методе объекта при доступе к несуществующей пропе
interface _IVector2 {
x: number;
y: number;
}
interface _IShape2D {
getNormals: ( v: string ) => _IVector2[];
}
export class Shape2D implements _IShape2D {
getNormals( v ) {
console.log( v.g );
^ ----- no error here
return [{} as _IVector2];
}
}
export const Test: _IShape2D = {
getNormals( v ) {
console.log( v.g );
^------ here we get expected error that
^------ 'g doesn`t exist on type string'
return [{} as _IVector2];
}
};
my tsconfig.json
{
"compilerOptions": {
"target": "es2017",
"allowSyntheticDefaultImports": true,
"checkJs": false,
"allowJs": true,
"noEmit": true,
"baseUrl": ".",
"moduleResolution": "node",
"strict": true,
"strictNullChecks": true,
"noImplicitAny": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noImplicitReturns": true,
"noImplicitThis": true,
"noFallthroughCasesInSwitch": true,
"jsx": "react",
"module": "commonjs",
"alwaysStrict": true,
"forceConsistentCasingInFileNames": true,
"esModuleInterop": true,
"noErrorTruncation": true,
"removeComments": true,
"resolveJsonModule": true,
"sourceMap": true,
"watch": true,
"skipLibCheck": true,
"paths": {
"@s/*": ["./src/*"],
"@i/*": ["./src/internal/*"]
}
},
"exclude": [
"node_modules"
]
}
Ожидается:- параметр метода класса должен быть выведен как строкаАктуально:- параметр метода выводится как любой
В конечном итоге мой вопрос заключается в следующем: «Является ли это поведение недостижимым в TS, и я должен прибегнуть к написанным от руки (о дорогой ...) цепочкам прототипов и простым объектам для прототипов? "
Заранее спасибо!