Skip to content

Commit

Permalink
add extra test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
Andarist committed Aug 19, 2024
1 parent f96d66e commit c0e99ae
Show file tree
Hide file tree
Showing 8 changed files with 747 additions and 85 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
contextualPropertyOfGenericFilteringMappedType.ts(38,5): error TS2353: Object literal may only specify known properties, and 'foo' does not exist in type '{ bar: (value: string, prop: "bar") => void; }'.
contextualPropertyOfGenericFilteringMappedType.ts(38,11): error TS7006: Parameter 'value' implicitly has an 'any' type.
contextualPropertyOfGenericFilteringMappedType.ts(38,18): error TS7006: Parameter 'key' implicitly has an 'any' type.


==== contextualPropertyOfGenericFilteringMappedType.ts (3 errors) ====
declare function f1<T extends object>(
data: T,
handlers: { [P in keyof T as P]: (value: T[P], prop: P) => void },
): void;

f1(
{
foo: 0,
bar: "",
},
{
foo: (value, key) => {},
bar: (value, key) => {},
},
);

declare function f2<T extends object>(
data: T,
handlers: { [P in keyof T as T[P] extends string ? P : never]: (value: T[P], prop: P) => void },
): void;

f2(
{
foo: 0,
bar: "",
},
{
bar: (value, key) => {},
},
);

f2(
{
foo: 0,
bar: "",
},
{
foo: (value, key) => {
~~~
!!! error TS2353: Object literal may only specify known properties, and 'foo' does not exist in type '{ bar: (value: string, prop: "bar") => void; }'.
~~~~~
!!! error TS7006: Parameter 'value' implicitly has an 'any' type.
~~~
!!! error TS7006: Parameter 'key' implicitly has an 'any' type.
// implicit `any`s
},
},
);

Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,24 @@ f2(
},
);

f2(
>f2 : Symbol(f2, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 14, 2))
{
foo: 0,
>foo : Symbol(foo, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 32, 3))

bar: "",
>bar : Symbol(bar, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 33, 11))

},
{
foo: (value, key) => {
>foo : Symbol(foo, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 36, 3))
>value : Symbol(value, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 37, 10))
>key : Symbol(key, Decl(contextualPropertyOfGenericFilteringMappedType.ts, 37, 16))

// implicit `any`s
},
},
);

Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,44 @@ f2(
},
);

f2(
>f2( { foo: 0, bar: "", }, { foo: (value, key) => { // implicit `any`s }, },) : void
> : ^^^^
>f2 : <T extends object>(data: T, handlers: { [P in keyof T as T[P] extends string ? P : never]: (value: T[P], prop: P) => void; }) => void
> : ^ ^^^^^^^^^ ^^ ^^ ^^ ^^ ^^^^^
{
>{ foo: 0, bar: "", } : { foo: number; bar: string; }
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

foo: 0,
>foo : number
> : ^^^^^^
>0 : 0
> : ^

bar: "",
>bar : string
> : ^^^^^^
>"" : ""
> : ^^

},
{
>{ foo: (value, key) => { // implicit `any`s }, } : { foo: (value: any, key: any) => void; }
> : ^^^^^^^^ ^^^^^^^ ^^^^^^^^^^^^^^^^^

foo: (value, key) => {
>foo : (value: any, key: any) => void
> : ^ ^^^^^^^ ^^^^^^^^^^^^^^
>(value, key) => { // implicit `any`s } : (value: any, key: any) => void
> : ^ ^^^^^^^ ^^^^^^^^^^^^^^
>value : any
> : ^^^
>key : any
> : ^^^

// implicit `any`s
},
},
);

Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
contextualTypeFunctionObjectPropertyIntersection.ts(84,5): error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{ FOO?: Action<{ type: "FOO"; }> | undefined; } & { "*"?: Action<{ type: "FOO"; } | { type: "bar"; }> | undefined; }'.
contextualTypeFunctionObjectPropertyIntersection.ts(84,11): error TS7006: Parameter 'ev' implicitly has an 'any' type.


==== contextualTypeFunctionObjectPropertyIntersection.ts (2 errors) ====
// repro from #48812

type Action<TEvent extends { type: string }> = (ev: TEvent) => void;

interface MachineConfig<TEvent extends { type: string }> {
schema: {
events: TEvent;
};
on?: {
[K in TEvent["type"]]?: Action<TEvent extends { type: K } ? TEvent : never>;
} & {
"*"?: Action<TEvent>;
};
}

declare function createMachine<TEvent extends { type: string }>(
config: MachineConfig<TEvent>
): void;

createMachine({
schema: {
events: {} as { type: "FOO" } | { type: "BAR" },
},
on: {
FOO: (ev) => {
ev.type; // should be 'FOO'
},
},
});

createMachine({
schema: {
events: {} as { type: "FOO" } | { type: "BAR" },
},
on: {
"*": (ev) => {
ev.type; // should be 'FOO' | 'BAR'
},
},
});

interface MachineConfig2<TEvent extends { type: string }> {
schema: {
events: TEvent;
};
on?: {
[K in TEvent["type"] as K extends Uppercase<string> ? K : never]?: Action<TEvent extends { type: K } ? TEvent : never>;
} & {
"*"?: Action<TEvent>;
};
}

declare function createMachine2<TEvent extends { type: string }>(
config: MachineConfig2<TEvent>
): void;

createMachine2({
schema: {
events: {} as { type: "FOO" } | { type: "bar" },
},
on: {
FOO: (ev) => {
ev.type; // should be 'FOO'
},
},
});

createMachine2({
schema: {
events: {} as { type: "FOO" } | { type: "bar" },
},
on: {
"*": (ev) => {
ev.type; // should be 'FOO' | 'bar'
},
},
});

createMachine2({
schema: {
events: {} as { type: "FOO" } | { type: "bar" },
},
on: {
bar: (ev) => {
~~~
!!! error TS2353: Object literal may only specify known properties, and 'bar' does not exist in type '{ FOO?: Action<{ type: "FOO"; }> | undefined; } & { "*"?: Action<{ type: "FOO"; } | { type: "bar"; }> | undefined; }'.
!!! related TS6500 contextualTypeFunctionObjectPropertyIntersection.ts:46:3: The expected type comes from property 'on' which is declared here on type 'MachineConfig2<{ type: "FOO"; } | { type: "bar"; }>'
~~
!!! error TS7006: Parameter 'ev' implicitly has an 'any' type.
ev // any
},
},
});

// repro from #49307#issuecomment-1143103607

declare function createSlice<T>(
reducers: { [K: string]: (state: string) => void } & {
[K in keyof T]: object;
}
): void;

createSlice({
f(a) {},
});

// repro from #49307#issuecomment-1196014488

type Validate<T> = T & { [K in keyof T]: object }
declare function f<S, T extends Record<string, (state: S) => any>>(s: S, x: Validate<T>): void;

f(0, {
foo: s => s + 1,
})

// repro from 49307#issuecomment-1195858950

type SliceCaseReducers<State> = Record<string, (state: State) => State | void>;

type ValidateSliceCaseReducers<S, ACR extends SliceCaseReducers<S>> = ACR & {
[T in keyof ACR]: ACR[T] extends {
reducer(s: S, action?: infer A): any;
}
? {
prepare(...a: never[]): Omit<A, "type">;
}
: {};
};

declare function createSlice<
State,
CaseReducers extends SliceCaseReducers<State>
>(options: {
initialState: State | (() => State);
reducers: ValidateSliceCaseReducers<State, CaseReducers>;
}): void;

export const clientSlice = createSlice({
initialState: {
username: "",
isLoggedIn: false,
userId: "",
avatar: "",
},
reducers: {
onClientUserChanged(state) {},
},
});


Loading

0 comments on commit c0e99ae

Please sign in to comment.