0
votes

I'm building a TypeScript library that leverages some interfaces from another library. I'm trying to define a type from the intersection of a generic type and an interface I don't control, combined with a union between void, which has special meaning in the dependency library.

I've tried to create a minimal representation of the issue I'm facing.

export type AllProps<Props> = (Props & IDependecyProps) | void;

interface MyProps {
  disableCache: boolean;
}

function doTheThing(props: AllProps<MyProps>) {
  // Property 'disableCache' does not exist on type 'AllProps'.
  //  Property 'disableCache' does not exist on type 'void'.ts(2339)
  console.log(props.disableCache);
}

My goal is that the AllProps should allow you to specify either disableCache, and any properties in IDependecyProps, OR the type results in void. The library I depend on has a special meaning for void type, which makes it useful.

EDIT: I made the code sample too simple, forgot to add the generic type.

2
How can there be type results in void? - Damian Green
The question is not really clear, but simple if will refine the type and exclude the void. Try - Aleksey L.
@AlekseyL., that was exactly all that was needed. Simple if(props) statement allowed TypeScript to exclude the void and assume my type intersection. It works perfectly :) - Andrew Craswell

2 Answers

0
votes

You can use a type assertion on your props and check for the existence of the property, since your example is boolean we need to check if it is not undefined

Read More Here


interface IDependecyProps {
    something: number
}
export type AllProps = (MyProps & IDependecyProps) | void;

interface MyProps {
  disableCache: boolean;
}

function doTheThing(props: AllProps) {

  if ( typeof((props as MyProps).disableCache)!=='undefined' )
  console.log((props as MyProps).disableCache);
}
doTheThing({ disableCache: false, something:1})

Playground

0
votes

Simple if will refine the type and exclude the void:

function doTheThing(props: AllProps) {
  if (props) {
    console.log(props.disableCache); // props is narrowed to MyProps & IDependecyProps
  }
}

Control flow analysis narrows type of props inside if to MyProps & IDependecyProps.

Also if is needed anyway to prevent error at runtime (props parameter can be undefined according to its type definition).

Playground