Use case
Some languages offer techniques to ensure certain requirements at compile time. For example, rust has the NonZeroU32
type that will ensure at compile time you can't assign a zero value to it without checking first.
In more complex cases, it can be hard to see if some set of constraints actually restricts the output type as expected. Consider this type in typescript:
type Obj = {... some fields};
const getObj = async<T extends keyof Obj> (id: number, fields: Array<T>): Promise<null | Pick<Obj, T>> =>
GET(`/api/${
id
}?fields=${fields.join(',')}`);
// This should fail
getObj(12, ["bla"]).foo
This is intended to return a type with only the fields passed as strings returned (the rest won't even be fetched from the API). However, the way this works is a bit convoluted and it would be easy to make a mistake that would lead to it allowing accessing other fields, which would crash at runtime. I would want to ensure that can't happen. I can't add test cases for this though because if it failed it would prevent the entire test suit from compiling.
This is just an example, I'm looking for language design features that would allow doing this naturally, not advice on this specific case.
Some other examples of failures I might want to test for:
let x: NonZeroU32 = 0;
or
println!("{}"); // bad macro parameters
Question
Do any languages have systems that allow testing code that does not compile? How might such a system be designed?
I'm not looking for advice for this case specifically but more generally if other languages have methods to deal with similar situation.
-B
"broken" option that uses duck typing? I mean, it seems close enough. $\endgroup$