Closed
Description
TypeScript Version: 4.1.0-beta (4.1.1-rc too)
//cc @mjbvz
Expected behavior:
No error on the following line
const selection = yield step;
As it works fine in TypeScript 4.0.5, and I'm unsure where the never
is even coming from. Here is the actual source if it is interesting: https://github.com/eamodio/vscode-gitlens/blob/787bc8f3a976135d51032547e209b93267e14b2f/src%2Fcommands%2FquickCommand.steps.ts#L1794-L1814
Actual behavior:
Error on the line
Type 'QuickPickStep<QuickPickItem>' is not assignable to type 'never'.(2322)
Related Issues:
Code
export enum Directive {
Back,
Cancel,
LoadMore,
Noop,
}
export namespace Directive {
export function is<T>(value: Directive | T): value is Directive {
return typeof value === 'number' && Directive[value] != null;
}
}
export interface QuickPickItem {
label: string;
description?: string;
detail?: string;
picked?: boolean;
alwaysShow?: boolean;
}
export interface QuickInputStep {
placeholder?: string;
prompt?: string;
title?: string;
}
export interface QuickPickStep<T extends QuickPickItem = QuickPickItem> {
placeholder?: string;
title?: string;
}
export type StepGenerator =
| Generator<QuickPickStep | QuickInputStep, StepResult<void | undefined>, any | undefined>
| AsyncGenerator<QuickPickStep | QuickInputStep, StepResult<void | undefined>, any | undefined>;
export type StepItemType<T> = T extends QuickPickStep<infer U> ? U[] : T extends QuickInputStep ? string : never;
export namespace StepResult {
export const Break = Symbol('BreakStep');
}
export type StepResult<T> = typeof StepResult.Break | T;
export type StepResultGenerator<T> =
| Generator<QuickPickStep | QuickInputStep, StepResult<T>, any | undefined>
| AsyncGenerator<QuickPickStep | QuickInputStep, StepResult<T>, any | undefined>;
export type StepSelection<T> = T extends QuickPickStep<infer U>
? U[] | Directive
: T extends QuickInputStep
? string | Directive
: never;
export type PartialStepState<T = unknown> = Partial<T> & { counter: number; confirm?: boolean; startingStep?: number };
export type StepState<T = Record<string, unknown>> = T & { counter: number; confirm?: boolean; startingStep?: number };
export function canPickStepContinue<T extends QuickPickStep>(
_step: T,
_state: PartialStepState,
_selection: StepItemType<T> | Directive,
): _selection is StepItemType<T> {
return false;
}
export function createPickStep<T extends QuickPickItem>(step: QuickPickStep<T>): QuickPickStep<T> {
return step;
}
export function* showStep<
State extends PartialStepState & { repo: any },
Context extends { repos: any[]; title: string; status: any }
>(state: State, _context: Context): StepResultGenerator<QuickPickItem> {
const step: QuickPickStep<QuickPickItem> = createPickStep<QuickPickItem>({
title: '',
placeholder: ''
});
const selection: StepSelection<typeof step> = yield step;
return canPickStepContinue(step, state, selection) ? selection[0] : StepResult.Break;
}
Output
export var Directive;
(function (Directive) {
Directive[Directive["Back"] = 0] = "Back";
Directive[Directive["Cancel"] = 1] = "Cancel";
Directive[Directive["LoadMore"] = 2] = "LoadMore";
Directive[Directive["Noop"] = 3] = "Noop";
})(Directive || (Directive = {}));
(function (Directive) {
function is(value) {
return typeof value === 'number' && Directive[value] != null;
}
Directive.is = is;
})(Directive || (Directive = {}));
export var StepResult;
(function (StepResult) {
StepResult.Break = Symbol('BreakStep');
})(StepResult || (StepResult = {}));
export function canPickStepContinue(_step, _state, _selection) {
return false;
}
export function createPickStep(step) {
return step;
}
export function* showStep(state, _context) {
const step = createPickStep({
title: '',
placeholder: ''
});
const selection = yield step;
return canPickStepContinue(step, state, selection) ? selection[0] : StepResult.Break;
}
Compiler Options
{
"compilerOptions": {
"noImplicitAny": true,
"strictNullChecks": true,
"strictFunctionTypes": true,
"strictPropertyInitialization": true,
"strictBindCallApply": true,
"noImplicitThis": true,
"noImplicitReturns": true,
"alwaysStrict": true,
"esModuleInterop": true,
"declaration": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"moduleResolution": 2,
"target": "ES2019",
"module": "ESNext"
}
}
Playground Link: Provided