Комментарии 41
при уже рабочем Blazor? Будут ли живы обе технологии или что то одно они похоронят?
Для чего будет нужен TypeScript, если теперь можно будет на C# под браузер писать?
TypeScript и Blazor/C# — слишком разные технологии, поэтому их сложно назвать конкурентами. Оба инструмента будут и дальше развиваться в своих нишах.
Да что мелочиться — все языки программирования вообще решают примерно одну и ту же задачу: выразить некое вычисление. Однако их много, и с годами становится только больше.
Как пример — Ruby в 2007 и Ruby в 2020. Очем я и спрашивал.
В моем понимании вещей, вероятность быть заброшенным куда выше у Blazor, нежели у Typescript.
Забросят его, конечно, вряд ли, но до "джаваскрипту капец", который предрекает DarthWazer еще ооочень далеко
Я застал предыдущую попытку завоевать веб с помощью C# — она называлась Silverlight. Как-то не взлетело.
Субъективно вижу только два кейса, на которых Blazor бы блистал:
- Перевод в веб легаси-кода на C#, который страшно или слишком дорого переписывать
- Написание веб-приложений новичками, которые знают только C# и хотят использовать его как серебряную пулю для решения абсолютно любых задач
Обе этих ниши довольно узкие, поэтому существование Blazor как таковое представляется скорее как попытка MS впрыгнуть в уезжающий поезд хайпа вокруг WASM. А хайп — штука довольно эфемерная.
Я только сейчас начал интересоваться TypeScript, вот это меня и беспокоит.
У многих языков есть возможность компилится в js тот же Dart, Scala, Kotlin и т.д и все это было задолго до Blazor. Как мы можем видеть до сих пор ничего из этого не взлетело. Так что я думаю что Blazor если и будет использоваться то только в стане C#, массовым он точно не станет.
Это обеспечит типобезопасную работу со списком аргументов.
Насчёт типобезопасности, мы до сих пор можем написать так:
const album = findSongAlbum('taylor swift', 'bad blood')
Конкретно в этом примере такое вряд ли произойдёт, но возникают ситуации когда хочется себя дополнительно обезопасить и определить типы SongTitle, ArtistName. В TS это можно сделать с помощью костылей вроде type branding, но в язык nominal typing добавлять пока не спешат.
А так хочется сказать: "В TypeScript X.Y наконец появилось то, чего я очень ждал" =)
А вообще да, номинальных типов, а также типов-подмножеств (только отрицательные/положительные, числа до 100, строки длиной (до) х символов) в определенных задачах не хватает, очень. Но спасибо и за то что есть. В крайнем случае, если уж очень нужно можно делать типы-обертки.
Чего вам особенно не хватает в TypeScript?
Иногда очень сильно нехватает второго дженерик параметра у Promise, обозначающего тип ошибки.
на самом деле ошибку невозможно типизировать. представьте http запрос с json ответом. вы можете получить ошибку с сетью, а можете получить ошибку того что пришел не json и распарсить результаты не вышло. в этих случаях вы получите разные ошибки. по хорошему нужно чтобы все ошибки в catch блоках были типа unknown как это (опционально) предложили делать в конструкции try-catch, что будет семантически правильно. но в целом достаточно .catch(err: Error) писать
поэтому eslint например требует что если используется явно Promise.reject(err) то err должно быть что-то Error-подобное.
А это не самообман? Я имею ввиду, что он отнюдь неспроста там any
(хотя имхо могли бы и unknown
сделать). Никто не гарантирует, что Promise упадёт именно с таким типом, который вы желаете увидеть.
да, я совсем не спорю, что в Promise.reject можно засунуть все что угодно. и поэтому привел пример, что в eslint есть правило, которое разрешает использовать Promise.reject только с объектами типа Error и производных (что для меня кажется очень правильным)
вы абсолютно правы, прилететь может всё что угодно. возможно, в будущем появится strict флаг в конфиге, чтобы ошибки в catch блоках были типа unknown по умолчанию. сейчас в этом месте не хватает строгости.
я в домашних проектах всегда включаю strict: true, так что буду рад такой опции
Не хочу плодить веткок, ответ для n-srg
Для примеров с запросами: у нас же все-равно есть какой-нибудь класс-прослойка между приложением и библиотекой для запросов. Можно обрабатывать ошибки там и приводить к нужному виду. Даже если будет несколько типов ошибок через |, ничего нам не помешает обработать их через type-guards.
тут непонятно какую задачу вы этим хотите решить. ведь нет такого состояния что вы точно знаете что вернется при ошибке.
окей вы однажды написали catch блок и уточнили тип ошибки.
дальше код изменился, неважно при вызове или где то сбоку (что особенно весело). И тут считай вы сам себе враг, потому что тайпскрипт не предложит отрефакторить catch он просто будет думать что все осталось как прежде. а на самом деле теперь прилетает ошибка совсем другого типа. тайпскрипт не помогает, и я пытаюсь понять в чем тогда профит
зато в 1% я буду гарантированно знать, какого типа у меня будет ошибка.
Повторюсь, по моему мнению, вы занимаетесь самообманом. Видимо вы устали писать код вида:
.catch(error => {
if (isBlaBlaError(error))
handleBlablaError(error);
else
handleUnknownError(error);
});
Предполагая, что handleUnknownError
чрезвычайно маловероятен. И желаете писать код вида:
.catch(handleBlaBlaError)
Всё так? Если да, то не проще ли сделать так:
.catch(genErrorHandler(blaBlaErrorPair))
Где blaBlaErrorPair
это комбо { guard: isBlaBlaError, handler: blaBlaErrorHandler }
? И волки сыты, о овцы целы. На мой взгляд желая Promise<Result, Error>
вы желаете странного :)
В TS4 хотя бы дали возможность типизировать как unknown
Чего не хватает, чего не хватает… очевидного не хватает — например, нормальной поддержки ООП для статических свойств/методов (abstract static не работает и protected static тоже; typeof MyClass нельзя; typeof this.constructor = Function, а не тип своего класса, и т.д.). Там много issues подобного рода висит открытыми годами.
например, нормальной поддержки ООП для статических свойств/методов (abstract static не работает и protected static тоже
А где abstract static работает? Во многих языках он не возможен — Java, C#, в php раньше можно было, потом запретили.
protected static работает в TS, например:
class Logger {
['constructor']: typeof Logger
protected static PREFIX = '[info]'
public log(message: string): void {
console.log(this.constructor.PREFIX + ' ' + message)
}
}
class Warner extends Logger {
protected static PREFIX = '[warn]'
}
const a = new Logger(); a.log('a')
const b = new Warner(); b.log('b')
Про "typeof MyClass нельзя" я не понял.
Я так понимаю, речь идет о конструкции вроде
function createInstance(classConstructor: typeof MyClass): MyClass {
return new classConstructor('some arg');
}
Сейчас можно только classConstructor: { new(someArg: string) => MyClass }
Работает же и так:
class MyClass {
constructor(arg: string) {
console.log(arg)
}
}
function createInstance(classConstructor: typeof MyClass): MyClass {
return new classConstructor('some arg')
}
createInstance(MyClass)
type Params: [title: string, artist: string]
const findSongAlbum: IQuery<Album, Params> = (title, artist) => {
Чем оно удобнее того же питона/с/java/go?
IQuery<Album> findSongAlbum(string title, string artist) {
...
В приведенном вами примере ваш код утверждает, что функция
findSongAlbum
вернет тип IQuery
НО, в примере из статьи, декларируется что переменная
findSongAlbum
имеет тип IQuery
. Этот тип, судя по всему является вызываемым (callable), проще говоря это тип-функция. Затем мы присваиваем этой переменной анонимную функцию, и поскольку ее тип уже известен, нет нужды проставлять типы параметров.function findSongAlbum(finder: (songs: Song[]) => Song) { //...
Более традиционный синтаксис тоже есть:
function findSongAlbum(title: string, artist: string): IQuery<Album> {
}
Видимо, ждут как пойдет с https://github.com/tc39/proposal-pattern-matching
В TypeScript 4.0 наконец появилось то, чего я очень ждал