2017-02-21 6 views
5

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

Flowtype дает мне ошибку для этого, если я пропустить проверку нулевой:

var myEl = new MyElement() 
if (document.body != null) { // error on next line if omitted 
    document.body.appendChild(myEl) 
} 

я должен сделать это проверить нуль для тела документа в каждом обратном вызове тоже, потому что, кто знает, может быть тело это null здесь правый ?! Я думаю, что это полный избыток. Не только это, но в чем смысл такого простого nullcheck? Он просто молча пропускает важную часть программы и демонстрирует неопределенное поведение где-то в другом месте и делает отладку приложения намного сложнее. Я бы предпочел просто иметь нулевое исключение на данный момент, если здесь случается ошибка, потому что для того, чтобы быть уверенным, что этот крошечный сегмент кода с двумя строками, который я бы написал в javascript, должен быть таким же в потоковом режиме:

var myEl = new MyElement() 
if (document.body != null) { 
    document.body.appendChild(myEl) 
} else { 
    console.error("null error") 
} 

4 дополнительных строки кода и некоторая вложенность только для того, чтобы отследить что-то, что я получил бы бесплатно, если бы я просто допустил ошибку приложения. И мне нужны эти 4 строки для каждого запроса. На каждом документе. На каждое имя getElementByTagName. Только это, вероятно, увеличивает мою кодовую базу на 10%. Какой смысл строго соблюдать это?

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

+0

Вы можете сделать 'if (! Document.body) throw new Error();' вместо 'if/else' и т. Д. В конце дня Flow выполняет свою работу здесь, что на 100% предотвращает ошибку времени выполнения, которая может быть уловлена ​​системой времени. 'try/catch' предназначен для обнаружения явных исключений, но проверки типа« null »отвечают за систему типов. Некоторые языки позволяют это делать, но Flow нет. – loganfsmyth

+0

@Blub my Я спрашиваю, что такое ошибка Flowtype? Это может быть полезно при ответе. Возможно, стоит отметить, что Flowtype можно рассматривать как тип Maybe, поэтому он не всегда является только кодом JavaScript. –

+0

@KevinTomiyoshiYang файл: '[flow] вызов метода 'appendChild' (метод не может быть вызван по возможному нулевому значению)' – Blub

ответ

7

Используя контролер типа, вы выбираете правила, которые он применяет. Доступ к объекту по типу с нулевым значением является одним из этих ограничений. Поэтому, если вы хотите иметь исключения для нулевых значений, вам нужно явно указать, чтобы доказать Flow, что это то, что вы хотите. Можно, например, сделать модуль как

if (!document.body) throw new Error("Unexpectedly missing <body>."); 
export const body: HTMLElement = document.body; 

export function querySelector(el: HTMLElement, selector: string): HTMLElement { 
    const result = el.querySelector(selector); 
    if (!result) throw new Error(`Failed to match: ${selector}`); 
    return result; 
} 

Бросая эти функции явно сказать: «Я вернусь элемент» во всех случаях, и в null случаях, они будут бросать исключения.

Затем в обычном коде, вы гарантированно вы можете использовать те

import {body, querySelector} from "./utils"; 

body.appendChild(document.createElement('div')); 

querySelector(body, 'div').setAttribute('thing', 'value'); 

и он будет typecheck недвижимости.

+2

Также стоит отметить, что потоки специальных случаев являются« инвариантными ». Вы можете «импортировать инвариант из« assert »или иным образом предоставлять реализацию для« инварианта », а затем вы можете просто написать' инвариантный (document.body) ', а не строку' if'/'throw', с которой вы столкнулись. Это быстрее, и IMO он читает лучше. –