Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Funny, just yesterday I found myself casting in a way I'd never seen before:

    const arr = ['foo'] as ['foo']
This wound up being useful in a situation that boiled down to:

    type SomeObj = { foo: string, bar: string }
    export const someFn = (props: (keyof SomeObj)[]) => {}

    // elsewhere
    const props = ['foo'] as ['foo']
    someFn(props)
In a case like that `as const` doesn't work, since the function doesn't expect a readonly argument. Of course there are several other ways to do it, but in my case the call site didn't currently import the SomeObj type, so casting "X as X" seemed like the simplest fix.


Why not use annotation instead?

  const props: ['foo'] = ['foo']


Didn't occur to me, that's certainly more defensible! Though maybe less humorous.


Or: cons foo = [‘foo’] as const;


> In a case like that `as const` doesn't work, since the function doesn't expect a readonly argument.


Ah, missed that. Sorry.


I don’t get this? why do I need to say as const?


`as const` is a special annotation that lets the TypeScript compiler infers the more specific type `["foo"]` instead of `string[]`.


As const creates a typed tuple instead of a typed array


You could also do

    const arr = ["foo" as const]


That's also different: "foo"[] as opposed to ["foo"] or readonly ["foo"].


I generally put lint rules to prevent casting, why cast here instead of declaring `props: (keyof SomeObj)[]` or `props: Parameters<typeof someFn>[0]`?


Er, my justification was that the code in question was meant to be minimally demonstrating someFn, and adding an import or a verbose type seemed to distract from that a little.

But mostly it just gave me a chuckle. I tried it because it seemed logical, but I didn't really think it was going to work until it did..




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: