Неправильный вывод типа при вводе текста в классе - PullRequest
1 голос
/ 06 октября 2019

При использовании композиционного подхода в машинописи над наследованием один я хочу описать свои сущности в соответствии с тем, что они «могут», а не с тем, что они «есть». Чтобы сделать это, мне нужно создать несколько сложных интерфейсов, а затем для своих классов (я использую классы, чтобы не создавать цепочку прототипов вручную и не нарушать некоторые оптимизации, которые, как я предполагаю, существуют внутри движков 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, и я должен прибегнуть к написанным от руки (о дорогой ...) цепочкам прототипов и простым объектам для прототипов? "

Заранее спасибо!

1 Ответ

0 голосов
/ 06 октября 2019

Это ограничение дизайна в TypeScript. Была попытка исправить , но она имела некоторые плохие / разрушительные взаимодействия с существующим реальным кодом, поэтому они отказались от него .

На данном этапе предлагается вручную аннотировать типы параметров при реализации / расширении классов;это лучше, чем прибегать к написанным вручную цепочкам прототипов, несмотря на то, что это более раздражает.

export class Shape2D implements _IShape2D {
  getNormals(v: string) { // annotate here
    console.log(v.g); // <-- error here as expected
    return [{} as _IVector2];
  }
}

Обратите внимание, что v действительно может быть any или unknown, а getNormals() будет правильной реализацией:

export class WeirdShape implements _IShape2D {
  getNormals(v: unknown) { // okay
    return [];
  }
}

Это связано с тем, что контравариантность параметра метода является типобезопасной ... a WeirdShape по-прежнему совершенно допустимо _IShape2D. Таким образом, хотя для параметра было бы неплохо выводиться как string, нет ничего неправильного в том, что он более общий.

В любом случае, надеюсь, это поможет;удачи!

Ссылка на код

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...