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

Seeing an announcement for a new version of some typescript library I've never heard of shoot to the top of the front page makes me feel extremely out of touch with mainstream dev.


What do you use for validation in TS? Anyone who deals with data should be validating/parsing it.


Effect Schema (the next incarnation of fp-ts/io-ts) is my go-to for parsing external data in TypeScript, and I heavily recommend it.


  const cached = new Map<string, Function>()

  export function as<T>(o: any, path: string, as: (o: any) => T | undefined) {
    try {
      let fn = cached.get(path)
      if (!fn) cached.set(path, fn = new Function('o', `return o.${path}`))
      const v = fn(o)
      return as(v) as T | undefined
    }
    catch (e) {
      return undefined
    }
  }

  as.number = (o: any) => (typeof o === 'number' ? o : undefined)
  as.string = (o: any) => (typeof o === 'string' ? o : undefined)
  as.boolean = (o: any) => (typeof o === 'boolean' ? o : undefined)
  as.numbers = (len = 0) => (o: any) => (o instanceof Array && o.length >= len && o.every(c => typeof c === 'number') ? o : undefined)
  as.strings = (len = 0) => (o: any) => (o instanceof Array && o.length >= len && o.every(c => typeof c === 'string') ? o : undefined)


  const size = as(usrConfig, 'sys.size', as.numbers(2))
  const fontpath = as(usrConfig, 'sys.font', as.string)


Great if that's the only validation you need, but I can't imagine using it in a real app, and there are some obvious bugs (e.g. never use `instanceof Array`).


Array.isArray isn't needed when you know your array isn't going to be deserialized e.g. via MessagePort. What other supposed bugs?

And yes I'm aware this doesn't have a huge API surface. That's the whole point. If I already have a JSON object, I can reach into it and get either what I ask for or nothing. In many real world cases, this is enough.


    let someArray = [1, 2, , 4];
    console.log(as.numbers(someArray) === someArray); // => true
    
    for (let number of numbers) {
        // This should be safe because I know everything in the array is a number, right?
        console.log(number.toFixed(2)); // => TypeError: number is undefined
    }
I mean, it's probably fine if you're only ever getting your data from JSON.parse(). But I would hesitate to use this in production.


> I mean, it's probably fine if you're only ever getting your data from JSON.parse().

So 90% of use cases?


Sure, and then only 10% of your use cases contain easily exploitable vulnerabilities.


You use a different function than Validate_Parsed_JSON in those cases. But most typescript programs are only going to need JSON-compatible input. Maybe some XML but that's also going to have similar formulaic output from your parser.

If something can directly hand you a maliciously built data structure, you're probably designing your system wrong. Are you running untrusted javascript in the same interpreter? That's a very hard problem that should be avoided if at all possible.

Basically, only working on JSON.parse is something to document but it's not at all a weird restriction, or a reason to balk at putting it into production.


The point is that it's layered.

1. Validate your Buffer/UInt8Array for valid size/encoding/etc first

2. Parse it to an object via JSON.parse or whatever your use-case needs

3. Reach into it with this function to get data if it matches the type you need

This code only deals with #3 and makes a few assumptions about #2 (e.g. no undefined, typical JSON-like object, etc).


If you don't do web dev (or at least, the latest web dev) then it's understandable, I often see lots of posts in the top spots whose languages I have no idea about either.


Zod is quite common, if not the most used validation library for JS/TS projects.




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

Search: