Description
TypeScript Version: 3.5.1 (also nightly, per playground)
Search Terms: mapped type interface generic parameter
Code
Sorry for the size of the repro. In TypeScript 3.3.3 this example-code type-checked without errors. As of (at least?) 3.5.1 and later I get the error:
function save(_response: IResponse<string>): void
Argument of type '(_response: IResponse<string>) => void' is not assignable to parameter of type 'IExportCallback<unknown>'.
Types of parameters '_response' and 'response' are incompatible.
Type 'IResponse<unknown>' is not assignable to type 'IResponse<string>'.
Type 'unknown' is not assignable to type 'string'.
export function save(_response: IRootResponse<string>): void {}
exportCommand(save);
declare function exportCommand<TResponse>(functionToCall: IExportCallback<TResponse>): void;
interface IExportCallback<TResponse> {
(response: IRootResponse<TResponse>): void;
}
type IRootResponse<TResponse> =
TResponse extends IRecord ? IRecordResponse<TResponse> : IResponse<TResponse>;
interface IRecord {
readonly Id: string;
}
declare type IRecordResponse<T extends IRecord> = IResponse<T> & {
sendRecord(): void;
};
declare type IResponse<T> = {
sendValue(name: keyof GetAllPropertiesOfType<T, string>): void;
};
/**
* Get the list of property names on type T that are of a given type
*/
declare type GetPropertyNamesOfType<T, RestrictToType> = {
[PropertyName in Extract<keyof T, string>]: T[PropertyName] extends RestrictToType ? PropertyName : never
}[Extract<keyof T, string>];
/**
* Get all the properties on type T that are of a given type
*/
declare type GetAllPropertiesOfType<T, RestrictToType> = Pick<
T,
GetPropertyNamesOfType<Required<T>, RestrictToType>
>;
Expected behavior:
The example program to type-check.
Actual behavior:
Example program does not type-check.
We can work-around this by supplying type-parameters to the invocation of exportCommand, however the (non-simplified) version of this bug comes up multiple times in our code-base, and it would be nice to infer the type-parameters from the passed-in callback (like we could prior to v3.5).
For the work-around, change the invocation of exportCommand exportCommand<string>(save);
(from exportCommand(save);
).
Playground Link:
Related Issues:
The auto-issue searcher thing in GitHub found issues that sounded similar but are listed as affecting versions prior to 3.3 (where this code worked):