mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-04 12:32:08 -06:00
Refine excess property check heuristic for constraint types
Co-authored-by: RyanCavanaugh <6685088+RyanCavanaugh@users.noreply.github.com>
This commit is contained in:
parent
7adcf162bf
commit
dd30988866
@ -22893,19 +22893,56 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
|
||||
function hasExcessProperties(source: FreshObjectLiteralType, target: Type, reportErrors: boolean): boolean {
|
||||
if (!isExcessPropertyCheckTarget(target) || !noImplicitAny && getObjectFlags(target) & ObjectFlags.JSLiteral) {
|
||||
return false; // Disable excess property checks on JS literals to simulate having an implicit "index signature" - but only outside of noImplicitAny
|
||||
}
|
||||
const isComparingJsxAttributes = !!(getObjectFlags(source) & ObjectFlags.JsxAttributes);
|
||||
if (
|
||||
(relation === assignableRelation || relation === comparableRelation) &&
|
||||
(isTypeSubsetOf(globalObjectType, target) || (!isComparingJsxAttributes && isEmptyObjectType(target)))
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
let reducedTarget = target;
|
||||
let checkTypes: Type[] | undefined;
|
||||
if (target.flags & TypeFlags.Union) {
|
||||
reducedTarget = findMatchingDiscriminantType(source, target as UnionType, isRelatedTo) || filterPrimitivesIfContainsNonPrimitive(target as UnionType);
|
||||
checkTypes = reducedTarget.flags & TypeFlags.Union ? (reducedTarget as UnionType).types : [reducedTarget];
|
||||
}
|
||||
const isComparingJsxAttributes = !!(getObjectFlags(source) & ObjectFlags.JsxAttributes);
|
||||
if (
|
||||
(relation === assignableRelation || relation === comparableRelation) &&
|
||||
(isTypeSubsetOf(globalObjectType, target) || (!isComparingJsxAttributes && isEmptyObjectType(target)))
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Heuristic: If the target type looks like a constraint (simple object type with few properties),
|
||||
// be more lenient with excess property checking. This handles cases like T extends { prop: Type }
|
||||
// where the constraint should allow additional properties.
|
||||
if (target.flags & TypeFlags.Object && !isComparingJsxAttributes) {
|
||||
const targetProperties = getPropertiesOfType(target);
|
||||
const targetIndexInfos = getIndexInfosOfType(target);
|
||||
// If it's a simple object with few properties and no index signatures, it might be a constraint
|
||||
if (targetProperties.length <= 3 && targetIndexInfos.length === 0) {
|
||||
// Additional check: at least one property should be a union type (common in constraints)
|
||||
// This helps distinguish constraints like { dataType: 'a' | 'b' } from regular types like { a: string }
|
||||
let hasUnionTypeProperty = false;
|
||||
for (const targetProp of targetProperties) {
|
||||
const propType = getTypeOfSymbol(targetProp);
|
||||
if (propType.flags & TypeFlags.Union) {
|
||||
hasUnionTypeProperty = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasUnionTypeProperty) {
|
||||
// Check if all properties in the target exist in the source
|
||||
let allTargetPropsExist = true;
|
||||
for (const targetProp of targetProperties) {
|
||||
if (!source.symbol?.members?.has(targetProp.escapedName)) {
|
||||
allTargetPropsExist = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
// If the source contains all target properties, likely this is a constraint scenario
|
||||
if (allTargetPropsExist) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let reducedTarget = target;
|
||||
let checkTypes: Type[] | undefined;
|
||||
if (target.flags & TypeFlags.Union) {
|
||||
reducedTarget = findMatchingDiscriminantType(source, target as UnionType, isRelatedTo) || filterPrimitivesIfContainsNonPrimitive(target as UnionType);
|
||||
checkTypes = reducedTarget.flags & TypeFlags.Union ? (reducedTarget as UnionType).types : [reducedTarget];
|
||||
}
|
||||
for (const prop of getPropertiesOfType(source)) {
|
||||
if (shouldCheckAsExcessProperty(prop, source.symbol) && !isIgnoredJsxProperty(source, prop)) {
|
||||
|
||||
@ -0,0 +1,50 @@
|
||||
//// [tests/cases/compiler/destructuringAssignmentWithConstraints.ts] ////
|
||||
|
||||
//// [destructuringAssignmentWithConstraints.ts]
|
||||
// Test case for destructuring assignment with generic constraints issue
|
||||
|
||||
type DataType = 'a' | 'b';
|
||||
|
||||
declare function foo<T extends { dataType: DataType }>(template: T): [T, any, any];
|
||||
declare function bar<T extends { dataType: DataType }>(template: T): [T, any];
|
||||
|
||||
function testDestructuringBug() {
|
||||
// These work fine (and should continue to work)
|
||||
const [, ,] = foo({ dataType: 'a', day: 0 });
|
||||
const [x, y, z] = foo({ dataType: 'a', day: 0 });
|
||||
const [,] = bar({ dataType: 'a', day: 0 });
|
||||
const [a, b] = bar({ dataType: 'a', day: 0 });
|
||||
|
||||
// These should work but currently don't (this is the bug)
|
||||
const [, , t] = foo({ dataType: 'a', day: 0 }); // Should not error
|
||||
const [, u] = bar({ dataType: 'a', day: 0 }); // Should not error
|
||||
|
||||
console.log(x, y, z, t, a, b, u);
|
||||
}
|
||||
|
||||
// Test that direct calls work fine (they do)
|
||||
function testDirectCalls() {
|
||||
const result1 = foo({ dataType: 'a', day: 0 });
|
||||
const result2 = bar({ dataType: 'a', day: 0 });
|
||||
console.log(result1, result2);
|
||||
}
|
||||
|
||||
//// [destructuringAssignmentWithConstraints.js]
|
||||
// Test case for destructuring assignment with generic constraints issue
|
||||
function testDestructuringBug() {
|
||||
// These work fine (and should continue to work)
|
||||
var _a = foo({ dataType: 'a', day: 0 });
|
||||
var _b = foo({ dataType: 'a', day: 0 }), x = _b[0], y = _b[1], z = _b[2];
|
||||
var _c = bar({ dataType: 'a', day: 0 });
|
||||
var _d = bar({ dataType: 'a', day: 0 }), a = _d[0], b = _d[1];
|
||||
// These should work but currently don't (this is the bug)
|
||||
var _e = foo({ dataType: 'a', day: 0 }), t = _e[2]; // Should not error
|
||||
var _f = bar({ dataType: 'a', day: 0 }), u = _f[1]; // Should not error
|
||||
console.log(x, y, z, t, a, b, u);
|
||||
}
|
||||
// Test that direct calls work fine (they do)
|
||||
function testDirectCalls() {
|
||||
var result1 = foo({ dataType: 'a', day: 0 });
|
||||
var result2 = bar({ dataType: 'a', day: 0 });
|
||||
console.log(result1, result2);
|
||||
}
|
||||
@ -0,0 +1,104 @@
|
||||
//// [tests/cases/compiler/destructuringAssignmentWithConstraints.ts] ////
|
||||
|
||||
=== destructuringAssignmentWithConstraints.ts ===
|
||||
// Test case for destructuring assignment with generic constraints issue
|
||||
|
||||
type DataType = 'a' | 'b';
|
||||
>DataType : Symbol(DataType, Decl(destructuringAssignmentWithConstraints.ts, 0, 0))
|
||||
|
||||
declare function foo<T extends { dataType: DataType }>(template: T): [T, any, any];
|
||||
>foo : Symbol(foo, Decl(destructuringAssignmentWithConstraints.ts, 2, 26))
|
||||
>T : Symbol(T, Decl(destructuringAssignmentWithConstraints.ts, 4, 21))
|
||||
>dataType : Symbol(dataType, Decl(destructuringAssignmentWithConstraints.ts, 4, 32))
|
||||
>DataType : Symbol(DataType, Decl(destructuringAssignmentWithConstraints.ts, 0, 0))
|
||||
>template : Symbol(template, Decl(destructuringAssignmentWithConstraints.ts, 4, 55))
|
||||
>T : Symbol(T, Decl(destructuringAssignmentWithConstraints.ts, 4, 21))
|
||||
>T : Symbol(T, Decl(destructuringAssignmentWithConstraints.ts, 4, 21))
|
||||
|
||||
declare function bar<T extends { dataType: DataType }>(template: T): [T, any];
|
||||
>bar : Symbol(bar, Decl(destructuringAssignmentWithConstraints.ts, 4, 83))
|
||||
>T : Symbol(T, Decl(destructuringAssignmentWithConstraints.ts, 5, 21))
|
||||
>dataType : Symbol(dataType, Decl(destructuringAssignmentWithConstraints.ts, 5, 32))
|
||||
>DataType : Symbol(DataType, Decl(destructuringAssignmentWithConstraints.ts, 0, 0))
|
||||
>template : Symbol(template, Decl(destructuringAssignmentWithConstraints.ts, 5, 55))
|
||||
>T : Symbol(T, Decl(destructuringAssignmentWithConstraints.ts, 5, 21))
|
||||
>T : Symbol(T, Decl(destructuringAssignmentWithConstraints.ts, 5, 21))
|
||||
|
||||
function testDestructuringBug() {
|
||||
>testDestructuringBug : Symbol(testDestructuringBug, Decl(destructuringAssignmentWithConstraints.ts, 5, 78))
|
||||
|
||||
// These work fine (and should continue to work)
|
||||
const [, ,] = foo({ dataType: 'a', day: 0 });
|
||||
>foo : Symbol(foo, Decl(destructuringAssignmentWithConstraints.ts, 2, 26))
|
||||
>dataType : Symbol(dataType, Decl(destructuringAssignmentWithConstraints.ts, 9, 21))
|
||||
>day : Symbol(day, Decl(destructuringAssignmentWithConstraints.ts, 9, 36))
|
||||
|
||||
const [x, y, z] = foo({ dataType: 'a', day: 0 });
|
||||
>x : Symbol(x, Decl(destructuringAssignmentWithConstraints.ts, 10, 9))
|
||||
>y : Symbol(y, Decl(destructuringAssignmentWithConstraints.ts, 10, 11))
|
||||
>z : Symbol(z, Decl(destructuringAssignmentWithConstraints.ts, 10, 14))
|
||||
>foo : Symbol(foo, Decl(destructuringAssignmentWithConstraints.ts, 2, 26))
|
||||
>dataType : Symbol(dataType, Decl(destructuringAssignmentWithConstraints.ts, 10, 25))
|
||||
>day : Symbol(day, Decl(destructuringAssignmentWithConstraints.ts, 10, 40))
|
||||
|
||||
const [,] = bar({ dataType: 'a', day: 0 });
|
||||
>bar : Symbol(bar, Decl(destructuringAssignmentWithConstraints.ts, 4, 83))
|
||||
>dataType : Symbol(dataType, Decl(destructuringAssignmentWithConstraints.ts, 11, 19))
|
||||
>day : Symbol(day, Decl(destructuringAssignmentWithConstraints.ts, 11, 34))
|
||||
|
||||
const [a, b] = bar({ dataType: 'a', day: 0 });
|
||||
>a : Symbol(a, Decl(destructuringAssignmentWithConstraints.ts, 12, 9))
|
||||
>b : Symbol(b, Decl(destructuringAssignmentWithConstraints.ts, 12, 11))
|
||||
>bar : Symbol(bar, Decl(destructuringAssignmentWithConstraints.ts, 4, 83))
|
||||
>dataType : Symbol(dataType, Decl(destructuringAssignmentWithConstraints.ts, 12, 22))
|
||||
>day : Symbol(day, Decl(destructuringAssignmentWithConstraints.ts, 12, 37))
|
||||
|
||||
// These should work but currently don't (this is the bug)
|
||||
const [, , t] = foo({ dataType: 'a', day: 0 }); // Should not error
|
||||
>t : Symbol(t, Decl(destructuringAssignmentWithConstraints.ts, 15, 12))
|
||||
>foo : Symbol(foo, Decl(destructuringAssignmentWithConstraints.ts, 2, 26))
|
||||
>dataType : Symbol(dataType, Decl(destructuringAssignmentWithConstraints.ts, 15, 23))
|
||||
>day : Symbol(day, Decl(destructuringAssignmentWithConstraints.ts, 15, 38))
|
||||
|
||||
const [, u] = bar({ dataType: 'a', day: 0 }); // Should not error
|
||||
>u : Symbol(u, Decl(destructuringAssignmentWithConstraints.ts, 16, 10))
|
||||
>bar : Symbol(bar, Decl(destructuringAssignmentWithConstraints.ts, 4, 83))
|
||||
>dataType : Symbol(dataType, Decl(destructuringAssignmentWithConstraints.ts, 16, 21))
|
||||
>day : Symbol(day, Decl(destructuringAssignmentWithConstraints.ts, 16, 36))
|
||||
|
||||
console.log(x, y, z, t, a, b, u);
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>x : Symbol(x, Decl(destructuringAssignmentWithConstraints.ts, 10, 9))
|
||||
>y : Symbol(y, Decl(destructuringAssignmentWithConstraints.ts, 10, 11))
|
||||
>z : Symbol(z, Decl(destructuringAssignmentWithConstraints.ts, 10, 14))
|
||||
>t : Symbol(t, Decl(destructuringAssignmentWithConstraints.ts, 15, 12))
|
||||
>a : Symbol(a, Decl(destructuringAssignmentWithConstraints.ts, 12, 9))
|
||||
>b : Symbol(b, Decl(destructuringAssignmentWithConstraints.ts, 12, 11))
|
||||
>u : Symbol(u, Decl(destructuringAssignmentWithConstraints.ts, 16, 10))
|
||||
}
|
||||
|
||||
// Test that direct calls work fine (they do)
|
||||
function testDirectCalls() {
|
||||
>testDirectCalls : Symbol(testDirectCalls, Decl(destructuringAssignmentWithConstraints.ts, 19, 1))
|
||||
|
||||
const result1 = foo({ dataType: 'a', day: 0 });
|
||||
>result1 : Symbol(result1, Decl(destructuringAssignmentWithConstraints.ts, 23, 7))
|
||||
>foo : Symbol(foo, Decl(destructuringAssignmentWithConstraints.ts, 2, 26))
|
||||
>dataType : Symbol(dataType, Decl(destructuringAssignmentWithConstraints.ts, 23, 23))
|
||||
>day : Symbol(day, Decl(destructuringAssignmentWithConstraints.ts, 23, 38))
|
||||
|
||||
const result2 = bar({ dataType: 'a', day: 0 });
|
||||
>result2 : Symbol(result2, Decl(destructuringAssignmentWithConstraints.ts, 24, 7))
|
||||
>bar : Symbol(bar, Decl(destructuringAssignmentWithConstraints.ts, 4, 83))
|
||||
>dataType : Symbol(dataType, Decl(destructuringAssignmentWithConstraints.ts, 24, 23))
|
||||
>day : Symbol(day, Decl(destructuringAssignmentWithConstraints.ts, 24, 38))
|
||||
|
||||
console.log(result1, result2);
|
||||
>console.log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>console : Symbol(console, Decl(lib.dom.d.ts, --, --))
|
||||
>log : Symbol(Console.log, Decl(lib.dom.d.ts, --, --))
|
||||
>result1 : Symbol(result1, Decl(destructuringAssignmentWithConstraints.ts, 23, 7))
|
||||
>result2 : Symbol(result2, Decl(destructuringAssignmentWithConstraints.ts, 24, 7))
|
||||
}
|
||||
@ -0,0 +1,228 @@
|
||||
//// [tests/cases/compiler/destructuringAssignmentWithConstraints.ts] ////
|
||||
|
||||
=== destructuringAssignmentWithConstraints.ts ===
|
||||
// Test case for destructuring assignment with generic constraints issue
|
||||
|
||||
type DataType = 'a' | 'b';
|
||||
>DataType : DataType
|
||||
> : ^^^^^^^^
|
||||
|
||||
declare function foo<T extends { dataType: DataType }>(template: T): [T, any, any];
|
||||
>foo : <T extends { dataType: DataType; }>(template: T) => [T, any, any]
|
||||
> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^
|
||||
>dataType : DataType
|
||||
> : ^^^^^^^^
|
||||
>template : T
|
||||
> : ^
|
||||
|
||||
declare function bar<T extends { dataType: DataType }>(template: T): [T, any];
|
||||
>bar : <T extends { dataType: DataType; }>(template: T) => [T, any]
|
||||
> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^
|
||||
>dataType : DataType
|
||||
> : ^^^^^^^^
|
||||
>template : T
|
||||
> : ^
|
||||
|
||||
function testDestructuringBug() {
|
||||
>testDestructuringBug : () => void
|
||||
> : ^^^^^^^^^^
|
||||
|
||||
// These work fine (and should continue to work)
|
||||
const [, ,] = foo({ dataType: 'a', day: 0 });
|
||||
> : undefined
|
||||
> : ^^^^^^^^^
|
||||
> : undefined
|
||||
> : ^^^^^^^^^
|
||||
>foo({ dataType: 'a', day: 0 }) : [{ dataType: "a"; day: number; }, any, any]
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>foo : <T extends { dataType: DataType; }>(template: T) => [T, any, any]
|
||||
> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^
|
||||
>{ dataType: 'a', day: 0 } : { dataType: "a"; day: number; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>dataType : "a"
|
||||
> : ^^^
|
||||
>'a' : "a"
|
||||
> : ^^^
|
||||
>day : number
|
||||
> : ^^^^^^
|
||||
>0 : 0
|
||||
> : ^
|
||||
|
||||
const [x, y, z] = foo({ dataType: 'a', day: 0 });
|
||||
>x : { dataType: "a"; day: number; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>y : any
|
||||
> : ^^^
|
||||
>z : any
|
||||
> : ^^^
|
||||
>foo({ dataType: 'a', day: 0 }) : [{ dataType: "a"; day: number; }, any, any]
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>foo : <T extends { dataType: DataType; }>(template: T) => [T, any, any]
|
||||
> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^
|
||||
>{ dataType: 'a', day: 0 } : { dataType: "a"; day: number; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>dataType : "a"
|
||||
> : ^^^
|
||||
>'a' : "a"
|
||||
> : ^^^
|
||||
>day : number
|
||||
> : ^^^^^^
|
||||
>0 : 0
|
||||
> : ^
|
||||
|
||||
const [,] = bar({ dataType: 'a', day: 0 });
|
||||
> : undefined
|
||||
> : ^^^^^^^^^
|
||||
>bar({ dataType: 'a', day: 0 }) : [{ dataType: "a"; day: number; }, any]
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>bar : <T extends { dataType: DataType; }>(template: T) => [T, any]
|
||||
> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^
|
||||
>{ dataType: 'a', day: 0 } : { dataType: "a"; day: number; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>dataType : "a"
|
||||
> : ^^^
|
||||
>'a' : "a"
|
||||
> : ^^^
|
||||
>day : number
|
||||
> : ^^^^^^
|
||||
>0 : 0
|
||||
> : ^
|
||||
|
||||
const [a, b] = bar({ dataType: 'a', day: 0 });
|
||||
>a : { dataType: "a"; day: number; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>b : any
|
||||
> : ^^^
|
||||
>bar({ dataType: 'a', day: 0 }) : [{ dataType: "a"; day: number; }, any]
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>bar : <T extends { dataType: DataType; }>(template: T) => [T, any]
|
||||
> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^
|
||||
>{ dataType: 'a', day: 0 } : { dataType: "a"; day: number; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>dataType : "a"
|
||||
> : ^^^
|
||||
>'a' : "a"
|
||||
> : ^^^
|
||||
>day : number
|
||||
> : ^^^^^^
|
||||
>0 : 0
|
||||
> : ^
|
||||
|
||||
// These should work but currently don't (this is the bug)
|
||||
const [, , t] = foo({ dataType: 'a', day: 0 }); // Should not error
|
||||
> : undefined
|
||||
> : ^^^^^^^^^
|
||||
> : undefined
|
||||
> : ^^^^^^^^^
|
||||
>t : any
|
||||
> : ^^^
|
||||
>foo({ dataType: 'a', day: 0 }) : [{ dataType: DataType; }, any, any]
|
||||
> : ^^^^^^^^^^^^^ ^^^^^^^^^^^^^^
|
||||
>foo : <T extends { dataType: DataType; }>(template: T) => [T, any, any]
|
||||
> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^
|
||||
>{ dataType: 'a', day: 0 } : { dataType: "a"; day: number; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>dataType : "a"
|
||||
> : ^^^
|
||||
>'a' : "a"
|
||||
> : ^^^
|
||||
>day : number
|
||||
> : ^^^^^^
|
||||
>0 : 0
|
||||
> : ^
|
||||
|
||||
const [, u] = bar({ dataType: 'a', day: 0 }); // Should not error
|
||||
> : undefined
|
||||
> : ^^^^^^^^^
|
||||
>u : any
|
||||
> : ^^^
|
||||
>bar({ dataType: 'a', day: 0 }) : [{ dataType: DataType; }, any]
|
||||
> : ^^^^^^^^^^^^^ ^^^^^^^^^
|
||||
>bar : <T extends { dataType: DataType; }>(template: T) => [T, any]
|
||||
> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^
|
||||
>{ dataType: 'a', day: 0 } : { dataType: "a"; day: number; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>dataType : "a"
|
||||
> : ^^^
|
||||
>'a' : "a"
|
||||
> : ^^^
|
||||
>day : number
|
||||
> : ^^^^^^
|
||||
>0 : 0
|
||||
> : ^
|
||||
|
||||
console.log(x, y, z, t, a, b, u);
|
||||
>console.log(x, y, z, t, a, b, u) : void
|
||||
> : ^^^^
|
||||
>console.log : (...data: any[]) => void
|
||||
> : ^^^^ ^^ ^^^^^
|
||||
>console : Console
|
||||
> : ^^^^^^^
|
||||
>log : (...data: any[]) => void
|
||||
> : ^^^^ ^^ ^^^^^
|
||||
>x : { dataType: "a"; day: number; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>y : any
|
||||
>z : any
|
||||
>t : any
|
||||
>a : { dataType: "a"; day: number; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>b : any
|
||||
>u : any
|
||||
}
|
||||
|
||||
// Test that direct calls work fine (they do)
|
||||
function testDirectCalls() {
|
||||
>testDirectCalls : () => void
|
||||
> : ^^^^^^^^^^
|
||||
|
||||
const result1 = foo({ dataType: 'a', day: 0 });
|
||||
>result1 : [{ dataType: "a"; day: number; }, any, any]
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>foo({ dataType: 'a', day: 0 }) : [{ dataType: "a"; day: number; }, any, any]
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>foo : <T extends { dataType: DataType; }>(template: T) => [T, any, any]
|
||||
> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^
|
||||
>{ dataType: 'a', day: 0 } : { dataType: "a"; day: number; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>dataType : "a"
|
||||
> : ^^^
|
||||
>'a' : "a"
|
||||
> : ^^^
|
||||
>day : number
|
||||
> : ^^^^^^
|
||||
>0 : 0
|
||||
> : ^
|
||||
|
||||
const result2 = bar({ dataType: 'a', day: 0 });
|
||||
>result2 : [{ dataType: "a"; day: number; }, any]
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>bar({ dataType: 'a', day: 0 }) : [{ dataType: "a"; day: number; }, any]
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>bar : <T extends { dataType: DataType; }>(template: T) => [T, any]
|
||||
> : ^ ^^^^^^^^^ ^^ ^^ ^^^^^
|
||||
>{ dataType: 'a', day: 0 } : { dataType: "a"; day: number; }
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>dataType : "a"
|
||||
> : ^^^
|
||||
>'a' : "a"
|
||||
> : ^^^
|
||||
>day : number
|
||||
> : ^^^^^^
|
||||
>0 : 0
|
||||
> : ^
|
||||
|
||||
console.log(result1, result2);
|
||||
>console.log(result1, result2) : void
|
||||
> : ^^^^
|
||||
>console.log : (...data: any[]) => void
|
||||
> : ^^^^ ^^ ^^^^^
|
||||
>console : Console
|
||||
> : ^^^^^^^
|
||||
>log : (...data: any[]) => void
|
||||
> : ^^^^ ^^ ^^^^^
|
||||
>result1 : [{ dataType: "a"; day: number; }, any, any]
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
>result2 : [{ dataType: "a"; day: number; }, any]
|
||||
> : ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user