Есть ли ошибка в компиляторе TypeScript относительно дженериков, или мне что-то не хватает? - PullRequest
0 голосов
/ 09 июля 2020

Я столкнулся с проблемой, которую невозможно исправить. Скажем, у меня есть следующий код:

interface HasId {
    id: string;
}

type Combiner<T> = {
    [key in keyof T]: T[key];
}

function testfn<T extends HasId>(args: Combiner<T>) {

}

class Person<T extends HasId> implements HasId {
    id: string;
    test() {
        testfn<T>({ id: this.id });
    }
}

Этот код только для примера, но не должно быть никаких ошибок. Однако проблема возникает вокруг этой строки:

testfn<T>({ id: this.id })

Он всегда, всегда, всегда выдает эту ошибку во время компиляции:

Argument of type '{ id: string; }' is not assignable to parameter of type 'Combiner<T>'

Но дело в том, что ошибка неправильная. { id: string } соответствует спецификациям типа Combiner!

Не только это, но и в VSCode предлагается добавить свойство id, когда я звоню testfn, что заставило меня поверить это ошибка компилятора.

Я ошибаюсь, или с этой ошибкой сталкиваются и другие люди?

Изменить:

вот мой tsconfig.json:

{
    "compilerOptions": {
        "strict": true,
        "experimentalDecorators": true,
        "module": "CommonJS",
        "target": "ES2019",
        "lib": ["ES2019"],
        "rootDir": "./src",
        "outDir": "./dist",
        "esModuleInterop": true,
        "strictPropertyInitialization": false
    },
    "include": [
        "./src"
    ],
    "exclude": [
        "./node_modules",
        "./dist"
    ]
}

1 Ответ

0 голосов
/ 09 июля 2020

Проблема в том, что в следующем выражении:

testfn<T>({ id: this.id });

Не гарантируется, что буквальное значение { id: this.id } расширяет T. Он расширяет HasId, но этого недостаточно.

Возможно, вы имеете дело не с Person<HasId>, а, например, с Person<{ id: 1, name: 'John' }> в какой-то момент, и поэтому возникает ошибка:

{ id: this.id } не может быть присвоено { id: number; name: string }

Если вам нужно значение id только внутри testFn, он не должен требовать параметризованный тип T, но он может быть достаточно написать (что решает проблему):

function testfn(args: Combiner<HasId>) {

}

Но я не уверен, что вы собираетесь делать с типом Combiner, который раньше зависел от T.

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