Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
913 views
in Technique[技术] by (71.8m points)

typescript - Checking if a value is valid for a union type

Suppose I have this type defined in my app:

type PiiType = 'name' | 'address' | 'email';

I use this type around the application to enforce some strong typing. We may get information from the server that ostensibly represents PII, and need to check if the type of the PII is valid or not by this type definition.

A previous solution suggested on this issue suggested having a second array duplicating the valid values, and checking strings against the contents of that array:

type PiiType = 'name' | 'address' | 'email';

isValidPii(value: string): Boolean {
  const piiTypeValues = ['name', 'address', 'email'];
  return piiTypeValues.indexOf(potentialValue) !== -1;
}

This is undesirable for us as it requires defining the type twice, removing a single source of truth and potentially creating errors.

How can I check if a given value is valid according to this union type, without duplicating its definition?

For example, if there was an operator like isoftype, I could use it like this:

'name' isoftype PiiType;      // true
'hamburger' isoftype PiiType; // false
100 isoftype PiiType;         // false

... but this operator doesn't exist, so I'm not sure what we should be doing instead to check if a value would be valid for this type. instanceof exists but only checks against classes/interfaces, and typeof only returns the JavaScript type (e.g. string or number).

We're considering using enums instead to represent this typing, but I'd like to check if there's something we can do with a native type instead first.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The trick is to run the array through an identity function that infers an element type constrained by string. That will cause the compiler to infer a union of literal types:

function asLiterals<T extends string>(arr: T[]): T[] { return arr; }
const piiTypeValues = asLiterals(['name', 'address', 'email']);
type PiiType = (typeof piiTypeValues)[number];

There's another solution here but the above seems a bit simpler.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...