kdavh
kdavh

Reputation: 414

Typescript: validate type after using type assertion

Is there a way to allow strict type checking on a value after having used a type assertion?

For example, sometimes I need to construct a function type that has attributes:

type FuncPlus = {
    (): void;
    anAttr: number;
    anotherAttr: Array<number>;
};

const f = (() => { }) as FuncPlus;
f.anAttr = 1;

f.anotherAttr.length # will error because `anotherAttr` is `undefined`

I want a clean way of constructing that still gives real type safety.

This is the closest that I've found, but it's not very "typescript-y":

const f: FuncPlus = Object.assign(
    () => { },
    {
        anAttr: 1,
        // without `anotherAttr` defined here, 
        // typescript will throw a compilation error, as desired
    }
)

Does anyone know another way?

Upvotes: 2

Views: 447

Answers (3)

geiner salcedo
geiner salcedo

Reputation: 31

Try

((f || {}).anotherAttr || {}).length

Upvotes: 0

Estus Flask
Estus Flask

Reputation: 222484

Object.assign is the way FuncPlus type should be assigned, it's already concise enough.

If there is small set of properties, helper function can be used to skip property names:

const getFuncPlus = (fn: () => void, anAttr: number, anotherAttr: number[]): FuncPlus =>
 Object.assign(fn, { anAttr, anotherAttr });

getFuncPlus(() => {}, 1) // causes an error

Upvotes: 1

Tyler Sebastian
Tyler Sebastian

Reputation: 9458

Would

type FuncPlus = {
  (): void;
  anAttr: undefined | number;
  anotherAttr: undefined | Array<number>;
};

satisfy your conditions?

const f = (() => {}) as FuncPlus;

f.anAttr = 1;
f.anAttr.toFixed() // good because of the above assignment

f.anotherAttr = "a" // errors - "a" is not assignable to type
f.anotherAttr.length // still errors // f.anotherAttr may be undefined

f.anotherAttr = []
f.anotherAttr.length // good

Upvotes: 0

Related Questions