Какова детальная логика утверждения типа в машинописи? - PullRequest
0 голосов
/ 25 апреля 2018

Я воспринимаю type assertion как что-то вроде Hi Compiler, I know the type of this variable better than you. Just follow me!.

Но похоже, что у компилятора все еще есть своя собственная логика для вывода типа.Например, предположим,

interface PM_MGEInfo {
    category: string;
    bid: string;
    cid?: string;
    labs?: { [key: string]: any };
}

Тогда 1 и 2 не являются проблемой, но 3 выдает ошибку TS2352.

  1. function makeMgeInfo(bid: string): PM_MGEInfo {
        return <PM_MGEInfo>{
            bid
        };
    }
    
  2. function makeMgeInfo(bid: string): PM_MGEInfo {
        return <PM_MGEInfo>{
            bid,
            labs: {}
        };
    }
    
  3. function makeMgeInfo(bid: string): PM_MGEInfo {
        return <PM_MGEInfo>{
            bid,
            // error TS2352: Type '{ labs: { poi_id: string; }; bid: string; }' cannot be converted to type 'PM_MGEInfo'.
            // Property 'category' is missing in type '{ labs: { poi_id: string; }; bid: string; }'.
            labs: {a: 1}
        };
    }
    

Почему type assertion начинает проверять другие поля в 3?Кто-то знает его логику деталей?


Обновлено: я создал проблему в Github Microsoft / TypeScript # 23698 .

Ответы [ 3 ]

0 голосов
/ 25 апреля 2018

Я думаю, что компилятор не распознает ваше значение {a: 1} как тип { [key: string]: any }, потому что если вы измените строку таким образом, ошибки компилятора не будет:

function makeMgeInfo(bid: string): PM_MGEInfo {
  return <PM_MGEInfo>{
    bid,
    labs: {a: 1} as {[key: string]: any}
  };
}

также работает, если вы определяете переменную следующим образом:

mylabs: {[key: string]: any} = {a: 1};

и вызовите его в своей функции:

makeMgeInfo(bid: string): PM_MGEInfo {
  return <PM_MGEInfo>{
    bid,
    labs: this.mylabs
  };
}

Поэтому я бы сказал, что компилятор не распознает ваш определенный тип из поля labs. Сообщение об ошибке в этом случае очень вводит в заблуждение.

0 голосов
/ 30 мая 2018

Проверьте спецификации 4.16. Тип Утверждения , вдохновленный этим ответом :

В выражении утверждения типа в форме e, e контекстно типизирован (раздел 4.23) с помощью T, и результирующий тип e должен быть назначен для T, или T должен быть назначен для расширенного форма результирующего типа e, или иначе возникает ошибка времени компиляции.

Для случая 1, T присваивается e, очевидно.

Для случая 2 расширенная форма e равна {bid: string, labs: Object}, которой можно присвоить T. Обратите внимание, что labs? присваивается Object ( На самом деле, я не уверен в этом, но это мое единственное возможное объяснение ).

Для случая 3 не выполняется ни одно из вышеуказанных условий.

0 голосов
/ 25 апреля 2018

вижу два варианта.Либо используйте Partial<T> или any.При использовании любого, ВЫ несете ответственность за то, чтобы все работало, поэтому используйте последний вариант.

Примеры обоих:

function makeMgeInfoWithPartial(bid: string): Partial<PM_MGEInfo> {
  // props are optional but only those defined by PM_MGEInfo are valid
  return {
    bid,
    labs: {a: 1}
  }
}

function makeMgeInfoWithAny(bid: string): PM_MGEInfo {
  return {
    bid,
    labs: {a: 1},
    whatever: 'also works'
  } as any
}
...