Hacker News new | ask | show | jobs
by eager_learner 24 days ago
function Greeting({ name }: { name: string }) { return ( <div class="card"> <h1>Hello, {name}!</h1> <p>Welcome to my site.</p> </div> ); }

That looks like HTML, but it's TypeScript. It gets compiled to actual HTML. Can any Python framework do that??

In Python, you'd typically write your logic in Python and your HTML in a separate Jinja2 template file — two languages, two files, context-switching. With Fresh + TSX, your logic and your markup live together in one .tsx file, both in TypeScript, with full type-checking throughout.

3 comments

No, that is not TypeScript. That's TSX. If you don't happen to have react, preact or a similar front end library, and a appropriate bundler, it is invalid TypeScript.

> That looks like HTML, but it's TypeScript. It gets compiled to actual HTML. Can any Python framework do that??

IMHO that's a terrible idea that no one should ever actually use, but if you are really in love with that, you can have it:

https://github.com/pyxy-org/pyxy

> If you don't happen to have react, preact or a similar front end library, and a appropriate bundler, it is invalid TypeScript.

Not true, you can compile it to HTML on the backend or even statically too.

It's not a terrible idea; it's actually amazing. One of Typescript's best features. I do agree at first it seems icky (reminds me of Qt's MOC) but in practice it's fantastic. I recommend you try it before criticising. Python has nothing close (nor do any other languages tbf).

> It's not a terrible idea; it's actually amazing.

You got it wrong, the terrible idea is `pyxy-org/pyxy`

>> invalid TypeScript.

> If you don't happen to have react, preact or a similar front end library, and a appropriate bundler, it is invalid TypeScript.

> Not true, you can compile it to HTML on the backend or even statically too.

I had to test your assertion that it compiles to HTML. I remember it being very invalid typescript without react scafolding. So I tested it without the react scafolding:

    # mise use node@24
    # echo '{}' >package.json
    # npm i --save typescript
    # echo 'function Greeting({ name }: { name: string }) { return ( <div class="card"> <h1>Hello, {name}!</h1> <p>Welcome to my site.</p> </div> ); }
    ' >hello.tsx
    # : a test to check if we have a working typescript compiler
    # tsc hello.tsx

    error TS5112: tsconfig.json is present but will not be loaded if files are specified on commandline. Use '--ignoreConfig' to skip this error.

    # echo '{"compilerOptions":{"jsx":"react"}}' >tsconfig.json
    # tsc

    hello.tsx:1:58 - error TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.

    1 function Greeting({ name }: { name: string }) { return ( <div class="card"> <h1>Hello, {name}!</h1> <p>Welcome to my site.</p> </div> ); }
                                                            ~~~~~~~~~~~~~~~~~~

    hello.tsx:1:59 - error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found.

    1 function Greeting({ name }: { name: string }) { return ( <div class="card"> <h1>Hello, {name}!</h1> <p>Welcome to my site.</p> </div> ); }
                                                                ~~~

    hello.tsx:1:77 - error TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.

    1 function Greeting({ name }: { name: string }) { return ( <div class="card"> <h1>Hello, {name}!</h1> <p>Welcome to my site.</p> </div> ); }
                                                                                ~~~~

    hello.tsx:1:78 - error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found.

    1 function Greeting({ name }: { name: string }) { return ( <div class="card"> <h1>Hello, {name}!</h1> <p>Welcome to my site.</p> </div> ); }
                                                                                ~~

    hello.tsx:1:95 - error TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.

    1 function Greeting({ name }: { name: string }) { return ( <div class="card"> <h1>Hello, {name}!</h1> <p>Welcome to my site.</p> </div> ); }
                                                                                                    ~~~~~

    hello.tsx:1:101 - error TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.

    1 function Greeting({ name }: { name: string }) { return ( <div class="card"> <h1>Hello, {name}!</h1> <p>Welcome to my site.</p> </div> ); }
                                                                                                        ~~~

    hello.tsx:1:102 - error TS2874: This JSX tag requires 'React' to be in scope, but it could not be found.

    1 function Greeting({ name }: { name: string }) { return ( <div class="card"> <h1>Hello, {name}!</h1> <p>Welcome to my site.</p> </div> ); }
                                                                                                        ~

    hello.tsx:1:123 - error TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.

    1 function Greeting({ name }: { name: string }) { return ( <div class="card"> <h1>Hello, {name}!</h1> <p>Welcome to my site.</p> </div> ); }
                                                                                                                                ~~~~

    hello.tsx:1:128 - error TS7026: JSX element implicitly has type 'any' because no interface 'JSX.IntrinsicElements' exists.

    1 function Greeting({ name }: { name: string }) { return ( <div class="card"> <h1>Hello, {name}!</h1> <p>Welcome to my site.</p> </div> ); }
                                                                                                                                    ~~~~~~

    Found 9 errors in the same file, starting at: hello.tsx:1

    # cat hello.js

    function Greeting({ name }) { return (React.createElement("div", { class: "card" }, " ", React.createElement("h1", null, "Hello, ", name, "!"), " ", React.createElement("p", null, "Welcome to my site."), " ")); }

    # : sanity check
    # mise use deno
    # deno hello.tsx

    # : no output

    # echo 'function Greeting({ name }: { name: string }) { return ( <div class="card"> <h1>Hello, {name}!</h1> <p>Welcome to my site.</p> </div> ); }; Greeting({ name: "world!" });' >hello2.tsx

    # deno hello2.tsx

    error: Uncaught (in promise) ReferenceError: React is not defined
        at Greeting (file:////hellotsx/hello.tsx:1:49)
        at file:////hellotsx/hello.tsx:1:141
Where is my static HTML? Oh, that requires react I guess.
That's the ugliest spaghetti i've seen in a long time. Why would anybody want to do that to themselves or their co-coders?

Yes, separating html out in jinja2 or whatever is far superior.

It's poorly formatted here of course. In reality it's better. As for why:

1. You can compose HTML using normal code - functions, loops, etc. No separate shitty template language or whatever.

2. You get full support for static typing and IDE code intelligence. That's huge and pretty much unique to TSX.

Looks like old-school PHP if I squint a little