Skip to content

Instantly share code, notes, and snippets.

@afarnsworth-valve
Last active December 15, 2017 18:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save afarnsworth-valve/93d1096d1410b0f2efb2c94f86de9c84 to your computer and use it in GitHub Desktop.
Save afarnsworth-valve/93d1096d1410b0f2efb2c94f86de9c84 to your computer and use it in GitHub Desktop.
Odd behavior with partial and pick in TypeScript
interface BaseObj_t
{
baseMember: string,
baseNumber: number
}
interface DerivedObj_t extends BaseObj_t
{
derivedMember: string
}
declare function PickBase<T, K extends keyof T>( obj: T, pick: Pick<T, K> ): void
declare function PartialBase<T>( obj: T, partial: Partial<T> ) : void;
function SimplePartial( obj: BaseObj_t )
{
let s: string = obj.baseMember;
PickBase( obj, { baseMember: 'foo' } );
PartialBase( obj, { baseMember: 'foo' } );
}
function DerivedPartial( obj: DerivedObj_t )
{
let s: string = obj.baseMember;
PickBase( obj, { baseMember: 'foo' } );
PartialBase( obj, { baseMember: 'foo' } );
let asBaseObj: BaseObj_t = obj;
PartialBase( asBaseObj, { baseMember: 'foo' } );
let baseObj: BaseObj_t = { baseMember: 'foo', baseNumber: 12 };
PartialBase( obj, baseObj );
}
function DerivedPartialGeneric<T extends BaseObj_t>( obj: T )
{
let s: string = obj.baseMember;
PickBase( obj, { baseMember: 'foo' } );
PartialBase( obj, { baseMember: 'foo' } ); // TS2345: Argument of type '{ baseMember: "foo"; }' is not assignable to parameter of type 'Partial<T>'.
let baseObj: BaseObj_t = { baseMember: 'foo', baseNumber: 12 };
PartialBase( obj, baseObj ); // TS2345: Argument of type 'BaseObj_t' is not assignable to parameter of type 'Partial<T>'
// this doesn't need a cast, and works fine
let asBaseObj: BaseObj_t = obj;
PartialBase( asBaseObj, { baseMember: 'foo' } );
// same idea, no error
SimplePartial( obj );
}
function IntersectionPartial<T>( obj: T & BaseObj_t )
{
let s: string = obj.baseMember;
PickBase( obj, { baseMember: 'foo' } );
PartialBase( obj, { baseMember: 'foo' } ); // TS2345: Argument of type '{ baseMember: "foo"; }' is not assignable to parameter of type 'Partial<T & BaseObj_t>'.
let baseObj: BaseObj_t = { baseMember: 'foo', baseNumber: 12 };
PartialBase( obj, baseObj ); // TS2345: Argument of type 'BaseObj_t' is not assignable to parameter of type 'Partial<T & BaseObj_t>'.
// this doesn't need a cast, and works fine
let asBaseObj: BaseObj_t = obj;
PartialBase( asBaseObj, { baseMember: 'foo' } );
// same idea, no error
SimplePartial( obj );
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment