Отсутствует предупреждение TSC о недопустимом назначении

Я пытаюсь написать файл определения типа TypeScript для библиотеки node-serialport. Библиотека экспортирует переменную parsers с двумя функциями: raw и readline. Последний не может использоваться как парсер напрямую - он производит парсер при вызове. Это фрагмент моей первой попытки создать файл определения типа:

/// <reference path="./node.d.ts" />
declare module "serialport" {

    import events = module("events");
    export interface ParserFunc {
        (eventEmitter: events.NodeEventEmitter, buffer: NodeBuffer): void;
    }

    interface Parsers {
        raw: ParserFunc;
        readline(delimiter?: string): ParserFunc;
    }

    export var parsers: Parsers;
}

Проблема, с которой я столкнулся, заключается в том, что tsc не предупреждает, если я назначу parsers.readline переменной типа ParserFunc. Для иллюстрации рассмотрим следующий файл TypeScript:

import sp = module("serialport");

var a: number = sp.parsers.raw; // not ok
var b: number = sp.parsers.readline; // not ok
var c: sp.ParserFunc = sp.parsers.raw; // ok!
var d: sp.ParserFunc = sp.parsers.readline; // not ok

Когда я компилирую / транспилирую этот файл с помощью tsc, я получаю:

test1.ts(3,16): Cannot convert 'sp.ParserFunc' to 'number'
test1.ts(4,16): Cannot convert '(delimiter?: string) => sp.ParserFunc' to 'number'

Но никакого предупреждения о присвоении d! Если я сделаю параметр delimiter для readline обязательным, удалив ?, я получу:

test1.ts(3,16): Cannot convert 'sp.ParserFunc' to 'number'
test1.ts(4,16): Cannot convert '(delimiter: string) => sp.ParserFunc' to 'number'
test1.ts(6,23): Cannot convert '(delimiter: string) => sp.ParserFunc' to 'sp.ParserFunc': Call signatures of types '(delimiter: string) => ParserFunc' and 'ParserFunc' are incompatible:
    Type 'String' is missing property 'addListener' from type 'NodeEventEmitter'

Итак, СЕЙЧАС он обнаруживает, что присвоение d недопустимо. Но почему не раньше?

Это моя первая встреча с TypeScript вообще, так что будьте осторожны. Спасибо! :-)


person provegard    schedule 08.03.2013    source источник
comment
Назначение не приведет к ошибке, потому что вы объявляете оба свойства типа ParserFunc. Однако второе объявление (строка чтения) на самом деле означает: у меня есть функция, которая имеет необязательную строку в качестве ввода и которая вернет мне что-то типа ParserFunc.   -  person thomaux    schedule 08.03.2013
comment
@Anzeo тип sp.parsers.readline (delimiter?: string) => serialport.ParserFunc, а не serialport.ParserFunc, поэтому он должен быть ошибочным.   -  person Fenton    schedule 08.03.2013


Ответы (1)


Мне это действительно кажется ошибкой. Похоже, компилятор предположил, что вы вызываете функцию, хотя это не так.

Я могу воссоздать это на упрощенном примере:

declare module serialport {

    export interface ParserFunc {
        (eventEmitter: number, buffer: string): void;
    }

    interface Parsers {
        raw: ParserFunc;
        readline(delimiter?: string): ParserFunc;
    }

    export var parsers: Parsers;
}

var c: serialport.ParserFunc = serialport.parsers.raw; // ok!
var d: serialport.ParserFunc = serialport.parsers.readline; // not ok

Итак, если бы readline действительно был вызван, это было бы правильно, но на самом деле readline передается без вызова, поэтому он должен показывать ошибку.

Вы можете сообщать об ошибках на веб-сайте TypeScript Codeplex.

person Fenton    schedule 08.03.2013
comment
Ага, это ошибка. Я поднял этот вопрос с командой, но не стесняйтесь регистрировать ошибку CodePlex, если хотите отследить проблему. Спасибо! - person Ryan Cavanaugh; 08.03.2013
comment
Спасибо, я отправлю отчет об ошибке! - person provegard; 08.03.2013