MCPcopy Create free account
hub / github.com/microsoft/typescript-go / inferFromTypes

Method inferFromTypes

internal/checker/inference.go:66–303  ·  view source on GitHub ↗
(n *InferenceState, source *Type, target *Type)

Source from the content-addressed store, hash-verified

64}
65
66func (c *Checker) inferFromTypes(n *InferenceState, source *Type, target *Type) {
67 if !c.couldContainTypeVariables(target) || c.isNoInferType(target) {
68 return
69 }
70 if source == c.wildcardType || source == c.blockedStringType {
71 // We are inferring from an 'any' type. We want to infer this type for every type parameter
72 // referenced in the target type, so we record it as the propagation type and infer from the
73 // target to itself. Then, as we find candidates we substitute the propagation type.
74 savePropagationType := n.propagationType
75 n.propagationType = source
76 c.inferFromTypes(n, target, target)
77 n.propagationType = savePropagationType
78 return
79 }
80 if source.alias != nil && target.alias != nil && source.alias.symbol == target.alias.symbol {
81 if len(source.alias.typeArguments) != 0 || len(target.alias.typeArguments) != 0 {
82 // Source and target are types originating in the same generic type alias declaration.
83 // Simply infer from source type arguments to target type arguments, with defaults applied.
84 params := c.typeAliasLinks.Get(source.alias.symbol).typeParameters
85 minParams := c.getMinTypeArgumentCount(params)
86 nodeIsInJsFile := ast.IsInJSFile(source.alias.symbol.ValueDeclaration)
87 sourceTypes := c.fillMissingTypeArguments(source.alias.typeArguments, params, minParams, nodeIsInJsFile)
88 targetTypes := c.fillMissingTypeArguments(target.alias.typeArguments, params, minParams, nodeIsInJsFile)
89 c.inferFromTypeArguments(n, sourceTypes, targetTypes, c.getAliasVariances(source.alias.symbol))
90 }
91 // And if there weren't any type arguments, there's no reason to run inference as the types must be the same.
92 return
93 }
94 if source == target && source.flags&TypeFlagsUnionOrIntersection != 0 {
95 // When source and target are the same union or intersection type, just relate each constituent
96 // type to itself.
97 for _, t := range source.Types() {
98 c.inferFromTypes(n, t, t)
99 }
100 return
101 }
102 if target.flags&TypeFlagsUnion != 0 {
103 var sourceTypes []*Type
104 if source.flags&TypeFlagsUnion != 0 {
105 sourceTypes = source.Types()
106 } else {
107 sourceTypes = []*Type{source}
108 }
109 // First, infer between identically matching source and target constituents and remove the
110 // matching types.
111 tempSources, tempTargets := c.inferFromMatchingTypes(n, sourceTypes, target.Distributed(), (*Checker).isTypeOrBaseIdenticalTo)
112 // Next, infer between closely matching source and target constituents and remove
113 // the matching types. Types closely match when they are instantiations of the same
114 // object type or instantiations of the same type alias.
115 sources, targets := c.inferFromMatchingTypes(n, tempSources, tempTargets, (*Checker).isTypeCloselyMatchedBy)
116 if len(targets) == 0 {
117 return
118 }
119 target = c.getUnionType(targets)
120 if len(sources) == 0 {
121 // All source constituents have been matched and there is nothing further to infer from.
122 // However, simply making no inferences is undesirable because it could ultimately mean
123 // inferring a type parameter constraint. Instead, make a lower priority inference from

Calls 15

isNoInferTypeMethod · 0.95
getAliasVariancesMethod · 0.95
getUnionTypeMethod · 0.95
inferWithPriorityMethod · 0.95
getIntersectionTypeMethod · 0.95
getActualTypeVariableMethod · 0.95

Tested by

no test coverage detected