ZEDE_CODE Telegram 68
Обычно я не пишу сюда технический материал. Но почему бы и не попробовать.

У меня дико неоднозначные ощущения от TS. Когда он только вышел, то вызывал эйфорию, так как обещалось очень многое...
Но годы идут и уже четкое понимание: этот язык обречен навечно остаться сырым.

На TS взвалили непосильную задачу: решить проблемы с типизацией TS для повышения DX.
А у JS хватает своих приколов: неопределённый тип у this. Почти что угодно может стать чем угодно. Расширение прототипов и тд…

Поэтому у TS крайне сложная модель системы типов которая то и дело дает сбои.

Сегодня я бы подсветил проблему у типа void. Что же он означает?
Что функция ничего не возвращает? Мммм не совсем. Это значит, что результат функции должен игнорироваться.
Те результат функции не должен ни на что влиять.

Делаем пару простых пассов с типами:
function foo(test: boolean): void {
if (test) {
// можем делать пустой возврат
return
}
// можем явно возвращать undefined
return undefined
}

function bar(test: boolean): void {
if (test) {
// (ОШИБКА!) другие falsy значения не прокатят
return false
}
// (ОШИБКА!) другие falsy значения не прокатят
return null
}


Пока вроде все хорошо. Но значит ли что void подобен undefined?
Продолжаем следить за руками
function baz(test: number): void {
if (test === 0) {
// результатом функции которая возвращает void может быть вызов функции возвращающий void
return (function(): void {})()
} else if (test === 1) {
// результатом функции которая возвращает void может быть вызов функции возвращающий undefined
return (function(): undefined {})()
} else if (test === 2) {
// (ОШИБКА!) а вот другие функции не пустит
return (function(): number { return 5 })()
}
}


Все еще никаких странностей. Но что будет если мы будем принимать ее в качестве аргумента
function qux(cb: () => void) {
    return cb()
}

// все хорошо
qux(function(): void {})

// и все еще все хорошо
qux(function(): undefined {})

// стоп что? Ошибки нет
qux(function(): number { return 5 })


Вот тут уже начинаются странности. И тут уже начинаются расхождения void с undefined. Те мы можем передать как аргумент функции которые возвращают что угодно (да даже never)
// все окей, вызывай функцию
qux(function(): never { throw 5 })


Что же это значит? Да то что любой тип может расширять void? Да нет
type isVoid<X> = X extends void ? true : false

type test1 = isVoid<undefined>
//   ^? true
type test2 = isVoid<null>
//   ^? false
type test3 = isVoid<never>
//   ^? never


Вроде не расширяется. Возвращаемся к нашим функциям и смотрим как расширяются void функции
type isVoidFunction<X> = X extends () => void ? true : false

type test4 = isVoidFunction<() => undefined>
//   ^? true

type test5 = isVoidFunction<() => null>
//   ^? true

type test6 = isVoidFunction<() => never>
//   ^? true


Вот оно как... Но это лишь подводка к главному примеру: void и сложение типов. void по своей сути говорит, что "игнорируй возвращаемое событие". Но если мы его смешиваем с другим значением, то TS закрывает руки и говорит "ну делай что хочешь"

const some = (cb: () => (void | number)) => {
    const value = cb() // void | number

// отсекаем void
    if (value) {
        value
        //^? number
    }
}

// ожидаем функцию которой все равно что вернет (например для мемоизации)
const example = (cb: () => void) => {
    return cb
}

// и ломаем рантайм к чертям, ибо TS пофиг
// он считает что () => 'hello' это расширение для () => void
// а вот JS пойдет по пути number
// так как 'hello' пройдет проверку на if (value)
some(example(() => 'hello'))


Вам кажется что тут пассы такие синтетические? Далеко ходить не нужно. union-ы с void вполне используются в коде React-а для useEffect
type Arg = Parameters<typeof useEffect>[0]
//    ^? () => void | Destructor

// Нет проблем. вот вам async коллбек для useEffect
// Конечно он не будет работать как надо, но TS доволен
useEffect(example(async () => {}), [])
🤯8🔥3🤔1



tgoop.com/zede_code/68
Create:
Last Update:

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

У меня дико неоднозначные ощущения от TS. Когда он только вышел, то вызывал эйфорию, так как обещалось очень многое...
Но годы идут и уже четкое понимание: этот язык обречен навечно остаться сырым.

На TS взвалили непосильную задачу: решить проблемы с типизацией TS для повышения DX.
А у JS хватает своих приколов: неопределённый тип у this. Почти что угодно может стать чем угодно. Расширение прототипов и тд…

Поэтому у TS крайне сложная модель системы типов которая то и дело дает сбои.

Сегодня я бы подсветил проблему у типа void. Что же он означает?
Что функция ничего не возвращает? Мммм не совсем. Это значит, что результат функции должен игнорироваться.
Те результат функции не должен ни на что влиять.

Делаем пару простых пассов с типами:

function foo(test: boolean): void {
if (test) {
// можем делать пустой возврат
return
}
// можем явно возвращать undefined
return undefined
}

function bar(test: boolean): void {
if (test) {
// (ОШИБКА!) другие falsy значения не прокатят
return false
}
// (ОШИБКА!) другие falsy значения не прокатят
return null
}


Пока вроде все хорошо. Но значит ли что void подобен undefined?
Продолжаем следить за руками
function baz(test: number): void {
if (test === 0) {
// результатом функции которая возвращает void может быть вызов функции возвращающий void
return (function(): void {})()
} else if (test === 1) {
// результатом функции которая возвращает void может быть вызов функции возвращающий undefined
return (function(): undefined {})()
} else if (test === 2) {
// (ОШИБКА!) а вот другие функции не пустит
return (function(): number { return 5 })()
}
}


Все еще никаких странностей. Но что будет если мы будем принимать ее в качестве аргумента
function qux(cb: () => void) {
    return cb()
}

// все хорошо
qux(function(): void {})

// и все еще все хорошо
qux(function(): undefined {})

// стоп что? Ошибки нет
qux(function(): number { return 5 })


Вот тут уже начинаются странности. И тут уже начинаются расхождения void с undefined. Те мы можем передать как аргумент функции которые возвращают что угодно (да даже never)
// все окей, вызывай функцию
qux(function(): never { throw 5 })


Что же это значит? Да то что любой тип может расширять void? Да нет
type isVoid<X> = X extends void ? true : false

type test1 = isVoid<undefined>
//   ^? true
type test2 = isVoid<null>
//   ^? false
type test3 = isVoid<never>
//   ^? never


Вроде не расширяется. Возвращаемся к нашим функциям и смотрим как расширяются void функции
type isVoidFunction<X> = X extends () => void ? true : false

type test4 = isVoidFunction<() => undefined>
//   ^? true

type test5 = isVoidFunction<() => null>
//   ^? true

type test6 = isVoidFunction<() => never>
//   ^? true


Вот оно как... Но это лишь подводка к главному примеру: void и сложение типов. void по своей сути говорит, что "игнорируй возвращаемое событие". Но если мы его смешиваем с другим значением, то TS закрывает руки и говорит "ну делай что хочешь"

const some = (cb: () => (void | number)) => {
    const value = cb() // void | number

// отсекаем void
    if (value) {
        value
        //^? number
    }
}

// ожидаем функцию которой все равно что вернет (например для мемоизации)
const example = (cb: () => void) => {
    return cb
}

// и ломаем рантайм к чертям, ибо TS пофиг
// он считает что () => 'hello' это расширение для () => void
// а вот JS пойдет по пути number
// так как 'hello' пройдет проверку на if (value)
some(example(() => 'hello'))


Вам кажется что тут пассы такие синтетические? Далеко ходить не нужно. union-ы с void вполне используются в коде React-а для useEffect
type Arg = Parameters<typeof useEffect>[0]
//    ^? () => void | Destructor

// Нет проблем. вот вам async коллбек для useEffect
// Конечно он не будет работать как надо, но TS доволен
useEffect(example(async () => {}), [])

BY zede code


Share with your friend now:
tgoop.com/zede_code/68

View MORE
Open in Telegram


Telegram News

Date: |

Joined by Telegram's representative in Brazil, Alan Campos, Perekopsky noted the platform was unable to cater to some of the TSE requests due to the company's operational setup. But Perekopsky added that these requests could be studied for future implementation. Channel login must contain 5-32 characters To upload a logo, click the Menu icon and select “Manage Channel.” In a new window, hit the Camera icon. With the administration mulling over limiting access to doxxing groups, a prominent Telegram doxxing group apparently went on a "revenge spree." The court said the defendant had also incited people to commit public nuisance, with messages calling on them to take part in rallies and demonstrations including at Hong Kong International Airport, to block roads and to paralyse the public transportation system. Various forms of protest promoted on the messaging platform included general strikes, lunchtime protests and silent sit-ins.
from us


Telegram zede code
FROM American