Currently, I am working on developing a unique "loose" nominal type that allows assignment from its base type, but restricts assignment from other nominal types with the same base type. Is there a way to modify the existing Nominal
type found here to achieve this functionality?
declare const nominalSymbol: unique symbol;
export type Nominal<T extends string, U> = U & { [nominalSymbol]: T };
I am looking to enhance this to create a type that behaves as follows:
export type LooseNominal<T extends string, U> = Nominal<T, U> | U; // while preventing direct assignment of nominal types derived from U
Here is an example of the desired behavior:
type Address = LooseNominal<'Address', string>;
type FirstName = LooseNominal<'FirstName', string>;
let address: Address = "123 Some St";
let firstName: FirstName = "John";
address = "456 Another St"; // this is okay
address = firstName; // This should result in a Type Error!
As of now, I have not found a way to impose a constraint like
U !extends Nominal<any, any>
. I experimented with U extends Nominal<T, any> ? never : U
, but encountered limitations that prevented it from functioning as intended as a nominal type.