Skip to content

Commit ffa21fe

Browse files
author
Andy Hanson
committed
getDeclarationOfKind: Improve type safety
1 parent d51e467 commit ffa21fe

File tree

4 files changed

+20
-20
lines changed

4 files changed

+20
-20
lines changed

src/compiler/checker.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2731,7 +2731,7 @@ namespace ts {
27312731
}
27322732

27332733
function symbolToParameterDeclaration(parameterSymbol: Symbol): ParameterDeclaration {
2734-
const parameterDeclaration = <ParameterDeclaration>getDeclarationOfKind(parameterSymbol, SyntaxKind.Parameter);
2734+
const parameterDeclaration = getDeclarationOfKind<ParameterDeclaration>(parameterSymbol, SyntaxKind.Parameter);
27352735
const parameterType = getTypeOfSymbol(parameterSymbol);
27362736
const parameterTypeNode = typeToTypeNodeHelper(parameterType);
27372737
// TODO(aozgaa): In the future, check initializer accessibility.
@@ -4100,7 +4100,7 @@ namespace ts {
41004100
const func = <FunctionLikeDeclaration>declaration.parent;
41014101
// For a parameter of a set accessor, use the type of the get accessor if one is present
41024102
if (func.kind === SyntaxKind.SetAccessor && !hasDynamicName(func)) {
4103-
const getter = <AccessorDeclaration>getDeclarationOfKind(declaration.parent.symbol, SyntaxKind.GetAccessor);
4103+
const getter = getDeclarationOfKind<AccessorDeclaration>(declaration.parent.symbol, SyntaxKind.GetAccessor);
41044104
if (getter) {
41054105
const getterSignature = getSignatureFromDeclaration(getter);
41064106
const thisParameter = getAccessorThisParameter(func as AccessorDeclaration);
@@ -4389,8 +4389,8 @@ namespace ts {
43894389
function getTypeOfAccessors(symbol: Symbol): Type {
43904390
const links = getSymbolLinks(symbol);
43914391
if (!links.type) {
4392-
const getter = <AccessorDeclaration>getDeclarationOfKind(symbol, SyntaxKind.GetAccessor);
4393-
const setter = <AccessorDeclaration>getDeclarationOfKind(symbol, SyntaxKind.SetAccessor);
4392+
const getter = getDeclarationOfKind<AccessorDeclaration>(symbol, SyntaxKind.GetAccessor);
4393+
const setter = getDeclarationOfKind<AccessorDeclaration>(symbol, SyntaxKind.SetAccessor);
43944394

43954395
if (getter && getter.flags & NodeFlags.JavaScriptFile) {
43964396
const jsDocType = getTypeForDeclarationFromJSDocComment(getter);
@@ -4439,7 +4439,7 @@ namespace ts {
44394439
if (!popTypeResolution()) {
44404440
type = anyType;
44414441
if (noImplicitAny) {
4442-
const getter = <AccessorDeclaration>getDeclarationOfKind(symbol, SyntaxKind.GetAccessor);
4442+
const getter = getDeclarationOfKind<AccessorDeclaration>(symbol, SyntaxKind.GetAccessor);
44434443
error(getter, Diagnostics._0_implicitly_has_return_type_any_because_it_does_not_have_a_return_type_annotation_and_is_referenced_directly_or_indirectly_in_one_of_its_return_expressions, symbolToString(symbol));
44444444
}
44454445
}
@@ -4916,7 +4916,7 @@ namespace ts {
49164916
return unknownType;
49174917
}
49184918

4919-
let declaration: JSDocTypedefTag | TypeAliasDeclaration = <JSDocTypedefTag>getDeclarationOfKind(symbol, SyntaxKind.JSDocTypedefTag);
4919+
let declaration: JSDocTypedefTag | TypeAliasDeclaration = getDeclarationOfKind<JSDocTypedefTag>(symbol, SyntaxKind.JSDocTypedefTag);
49204920
let type: Type;
49214921
if (declaration) {
49224922
if (declaration.jsDocTypeLiteral) {
@@ -4927,7 +4927,7 @@ namespace ts {
49274927
}
49284928
}
49294929
else {
4930-
declaration = <TypeAliasDeclaration>getDeclarationOfKind(symbol, SyntaxKind.TypeAliasDeclaration);
4930+
declaration = getDeclarationOfKind<TypeAliasDeclaration>(symbol, SyntaxKind.TypeAliasDeclaration);
49314931
type = getTypeFromTypeNode(declaration.type);
49324932
}
49334933

@@ -6220,7 +6220,7 @@ namespace ts {
62206220
!hasDynamicName(declaration) &&
62216221
(!hasThisParameter || !thisParameter)) {
62226222
const otherKind = declaration.kind === SyntaxKind.GetAccessor ? SyntaxKind.SetAccessor : SyntaxKind.GetAccessor;
6223-
const other = <AccessorDeclaration>getDeclarationOfKind(declaration.symbol, otherKind);
6223+
const other = getDeclarationOfKind<AccessorDeclaration>(declaration.symbol, otherKind);
62246224
if (other) {
62256225
thisParameter = getAnnotatedAccessorThisParameter(other);
62266226
}
@@ -6263,7 +6263,7 @@ namespace ts {
62636263
// TypeScript 1.0 spec (April 2014):
62646264
// If only one accessor includes a type annotation, the other behaves as if it had the same type annotation.
62656265
if (declaration.kind === SyntaxKind.GetAccessor && !hasDynamicName(declaration)) {
6266-
const setter = <AccessorDeclaration>getDeclarationOfKind(declaration.symbol, SyntaxKind.SetAccessor);
6266+
const setter = getDeclarationOfKind<AccessorDeclaration>(declaration.symbol, SyntaxKind.SetAccessor);
62676267
return getAnnotatedAccessorType(setter);
62686268
}
62696269

@@ -6476,7 +6476,7 @@ namespace ts {
64766476
}
64776477

64786478
function getConstraintDeclaration(type: TypeParameter) {
6479-
return (<TypeParameterDeclaration>getDeclarationOfKind(type.symbol, SyntaxKind.TypeParameter)).constraint;
6479+
return getDeclarationOfKind<TypeParameterDeclaration>(type.symbol, SyntaxKind.TypeParameter).constraint;
64806480
}
64816481

64826482
function getConstraintFromTypeParameter(typeParameter: TypeParameter): Type {
@@ -12567,7 +12567,7 @@ namespace ts {
1256712567
// corresponding set accessor has a type annotation, return statements in the function are contextually typed
1256812568
if (functionDecl.type ||
1256912569
functionDecl.kind === SyntaxKind.Constructor ||
12570-
functionDecl.kind === SyntaxKind.GetAccessor && getSetAccessorTypeAnnotationNode(<SetAccessorDeclaration>getDeclarationOfKind(functionDecl.symbol, SyntaxKind.SetAccessor))) {
12570+
functionDecl.kind === SyntaxKind.GetAccessor && getSetAccessorTypeAnnotationNode(getDeclarationOfKind<SetAccessorDeclaration>(functionDecl.symbol, SyntaxKind.SetAccessor))) {
1257112571
return getReturnTypeOfSignature(getSignatureFromDeclaration(functionDecl));
1257212572
}
1257312573

@@ -18110,7 +18110,7 @@ namespace ts {
1811018110
// TypeScript 1.0 spec (April 2014): 8.4.3
1811118111
// Accessors for the same member name must specify the same accessibility.
1811218112
const otherKind = node.kind === SyntaxKind.GetAccessor ? SyntaxKind.SetAccessor : SyntaxKind.GetAccessor;
18113-
const otherAccessor = <AccessorDeclaration>getDeclarationOfKind(node.symbol, otherKind);
18113+
const otherAccessor = getDeclarationOfKind<AccessorDeclaration>(node.symbol, otherKind);
1811418114
if (otherAccessor) {
1811518115
if ((getModifierFlags(node) & ModifierFlags.AccessibilityModifier) !== (getModifierFlags(otherAccessor) & ModifierFlags.AccessibilityModifier)) {
1811618116
error(node.name, Diagnostics.Getter_and_setter_accessors_do_not_agree_in_visibility);
@@ -20242,7 +20242,7 @@ namespace ts {
2024220242
}
2024320243

2024420244
function isGetAccessorWithAnnotatedSetAccessor(node: FunctionLikeDeclaration) {
20245-
return !!(node.kind === SyntaxKind.GetAccessor && getSetAccessorTypeAnnotationNode(<SetAccessorDeclaration>getDeclarationOfKind(node.symbol, SyntaxKind.SetAccessor)));
20245+
return !!(node.kind === SyntaxKind.GetAccessor && getSetAccessorTypeAnnotationNode(getDeclarationOfKind<SetAccessorDeclaration>(node.symbol, SyntaxKind.SetAccessor)));
2024620246
}
2024720247

2024820248
function isUnwrappedReturnTypeVoidOrAny(func: FunctionLikeDeclaration, returnType: Type): boolean {
@@ -20930,7 +20930,7 @@ namespace ts {
2093020930
checkTypeParameterListsIdentical(symbol);
2093120931

2093220932
// Only check this symbol once
20933-
const firstInterfaceDecl = <InterfaceDeclaration>getDeclarationOfKind(symbol, SyntaxKind.InterfaceDeclaration);
20933+
const firstInterfaceDecl = getDeclarationOfKind<InterfaceDeclaration>(symbol, SyntaxKind.InterfaceDeclaration);
2093420934
if (node === firstInterfaceDecl) {
2093520935
const type = <InterfaceType>getDeclaredTypeOfSymbol(symbol);
2093620936
const typeWithThis = getTypeWithThisArgument(type);

src/compiler/utilities.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@ namespace ts {
1111
isTypeReferenceDirective?: boolean;
1212
}
1313

14-
export function getDeclarationOfKind(symbol: Symbol, kind: SyntaxKind): Declaration {
14+
export function getDeclarationOfKind<T extends Declaration>(symbol: Symbol, kind: T["kind"]): T {
1515
const declarations = symbol.declarations;
1616
if (declarations) {
1717
for (const declaration of declarations) {
1818
if (declaration.kind === kind) {
19-
return declaration;
19+
return declaration as T;
2020
}
2121
}
2222
}

src/services/findAllReferences.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -550,15 +550,15 @@ namespace ts.FindAllReferences.Core {
550550
}
551551

552552
function isObjectBindingPatternElementWithoutPropertyName(symbol: Symbol): boolean {
553-
const bindingElement = <BindingElement>getDeclarationOfKind(symbol, SyntaxKind.BindingElement);
553+
const bindingElement = getDeclarationOfKind<BindingElement>(symbol, SyntaxKind.BindingElement);
554554
return bindingElement &&
555555
bindingElement.parent.kind === SyntaxKind.ObjectBindingPattern &&
556556
!bindingElement.propertyName;
557557
}
558558

559559
function getPropertySymbolOfObjectBindingPatternWithoutPropertyName(symbol: Symbol, checker: TypeChecker): Symbol | undefined {
560560
if (isObjectBindingPatternElementWithoutPropertyName(symbol)) {
561-
const bindingElement = <BindingElement>getDeclarationOfKind(symbol, SyntaxKind.BindingElement);
561+
const bindingElement = getDeclarationOfKind<BindingElement>(symbol, SyntaxKind.BindingElement);
562562
const typeOfPattern = checker.getTypeAtLocation(bindingElement.parent);
563563
return typeOfPattern && checker.getPropertyOfType(typeOfPattern, (<Identifier>bindingElement.name).text);
564564
}

src/services/symbolDisplay.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -275,7 +275,7 @@ namespace ts.SymbolDisplay {
275275
}
276276
if (symbolFlags & SymbolFlags.Module) {
277277
addNewLineIfDisplayPartsExist();
278-
const declaration = <ModuleDeclaration>getDeclarationOfKind(symbol, SyntaxKind.ModuleDeclaration);
278+
const declaration = getDeclarationOfKind<ModuleDeclaration>(symbol, SyntaxKind.ModuleDeclaration);
279279
const isNamespace = declaration && declaration.name && declaration.name.kind === SyntaxKind.Identifier;
280280
displayParts.push(keywordPart(isNamespace ? SyntaxKind.NamespaceKeyword : SyntaxKind.ModuleKeyword));
281281
displayParts.push(spacePart());
@@ -296,7 +296,7 @@ namespace ts.SymbolDisplay {
296296
}
297297
else {
298298
// Method/function type parameter
299-
let declaration = <Node>getDeclarationOfKind(symbol, SyntaxKind.TypeParameter);
299+
let declaration: Node = getDeclarationOfKind(symbol, SyntaxKind.TypeParameter);
300300
Debug.assert(declaration !== undefined);
301301
declaration = declaration.parent;
302302

0 commit comments

Comments
 (0)