2

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?

4
  • When you use a type assertion, you will lose any ability to verify that the your object is constructed properly when initializing. Type assertion differs from type casting in that it is telling the compiler to treat the object as another type (and the compiler will not do anything to verify that you aren't wrong). Commented Apr 30, 2018 at 21:03
  • Why do you say that your resulting code isn't "typescript-y"? Commented Apr 30, 2018 at 21:11
  • Because it seems more like a work-around than a pattern that anyone designing typescript would have been planning on. Commented May 2, 2018 at 5:48
  • Well, it is kind of atypical to have static properties on functions. The only way to do that in an assignment is to do it using Object.assign(...). Commented May 2, 2018 at 13:10

3 Answers 3

1

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
Sign up to request clarification or add additional context in comments.

Comments

0

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

1 Comment

My hope is to have a strongly typed structure that doesn't allow undefined
0

Try

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.