build/lib/treeshaking.ts/shouldSkipAlias
function getRealNodeSymbol(ts: typeof import('typescript'), checker: ts.TypeChecker, node: ts.Node): [ts.Symbol | null, ts.Declaration | null] {

	// Use some TypeScript internals to avoid code duplication
	type ObjectLiteralElementWithName = ts.ObjectLiteralElement & { name: ts.PropertyName; parent: ts.ObjectLiteralExpression | ts.JsxAttributes };
	const getPropertySymbolsFromContextualType: (node: ObjectLiteralElementWithName, checker: ts.TypeChecker, contextualType: ts.Type, unionSymbolOk: boolean) => ReadonlyArray<ts.Symbol> = (<any>ts).getPropertySymbolsFromContextualType;
	const getContainingObjectLiteralElement: (node: ts.Node) => ObjectLiteralElementWithName | undefined = (<any>ts).getContainingObjectLiteralElement;
	const getNameFromPropertyName: (name: ts.PropertyName) => string | undefined = (<any>ts).getNameFromPropertyName;

	// Go to the original declaration for cases:
	//
	//   (1) when the aliased symbol was declared in the location(parent).
	//   (2) when the aliased symbol is originating from an import.
	//
	function shouldSkipAlias(node: ts.Node, declaration: ts.Node): boolean {
		if (!ts.isShorthandPropertyAssignment(node) && node.kind !== ts.SyntaxKind.Identifier) {
			return false;
		}
		if (node.parent === declaration) {
			return true;
		}
		switch (declaration.kind) {
			case ts.SyntaxKind.ImportClause:
			case ts.SyntaxKind.ImportEqualsDeclaration:
				return true;
			case ts.SyntaxKind.ImportSpecifier:
				return declaration.parent.kind === ts.SyntaxKind.NamedImports;
			default:
				return false;
		}
	}

	if (!ts.isShorthandPropertyAssignment(node)) {
		if (node.getChildCount() !== 0) {
			return [null, null];
		}
	}

	const { parent } = node;

	let symbol = (
		ts.isShorthandPropertyAssignment(node)
			? checker.getShorthandAssignmentValueSymbol(node)
			: checker.getSymbolAtLocation(node)
	);

	let importNode: ts.Declaration | null = null;
	// If this is an alias, and the request came at the declaration location
	// get the aliased symbol instead. This allows for goto def on an import e.g.
	//   import {A, B} from "mod";
	// to jump to the implementation directly.
	if (symbol && symbol.flags & ts.SymbolFlags.Alias && symbol.declarations && shouldSkipAlias(node, symbol.declarations[0])) {
		const aliased = checker.getAliasedSymbol(symbol);
		if (aliased.declarations) {
			// We should mark the import as visited
			importNode = symbol.declarations[0];
			symbol = aliased;
		}
	}

	if (symbol) {
		// Because name in short-hand property assignment has two different meanings: property name and property value,
		// using go-to-definition at such position should go to the variable declaration of the property value rather than
		// go to the declaration of the property name (in this case stay at the same position). However, if go-to-definition
		// is performed at the location of property access, we would like to go to definition of the property in the short-hand
		// assignment. This case and others are handled by the following code.
		if (node.parent.kind === ts.SyntaxKind.ShorthandPropertyAssignment) {
			symbol = checker.getShorthandAssignmentValueSymbol(symbol.valueDeclaration);
		}

		// If the node is the name of a BindingElement within an ObjectBindingPattern instead of just returning the
		// declaration the symbol (which is itself), we should try to get to the original type of the ObjectBindingPattern
		// and return the property declaration for the referenced property.
		// For example:
		//      import('./foo').then(({ b/*goto*/ar }) => undefined); => should get use to the declaration in file "./foo"
		//
		//      function bar<T>(onfulfilled: (value: T) => void) { //....}
		//      interface Test {
		//          pr/*destination*/op1: number
		//      }
		//      bar<Test>(({pr/*goto*/op1})=>{});
		if (ts.isPropertyName(node) && ts.isBindingElement(parent) && ts.isObjectBindingPattern(parent.parent) &&
			(node === (parent.propertyName || parent.name))) {
			const name = getNameFromPropertyName(node);
			const type = checker.getTypeAtLocation(parent.parent);
			if (name && type) {
				if (type.isUnion()) {
					const prop = type.types[0].getProperty(name);
					if (prop) {
						symbol = prop;
					}
				} else {
					const prop = type.getProperty(name);
					if (prop) {
						symbol = prop;
					}
				}
			}
		}

		// If the current location we want to find its definition is in an object literal, try to get the contextual type for the
		// object literal, lookup the property symbol in the contextual type, and use this for goto-definition.
		// For example
		//      interface Props{
		//          /*first*/prop1: number
		//          prop2: boolean
		//      }
		//      function Foo(arg: Props) {}
		//      Foo( { pr/*1*/op1: 10, prop2: false })
		const element = getContainingObjectLiteralElement(node);
		if (element) {
			const contextualType = element && checker.getContextualType(element.parent);
			if (contextualType) {
				const propertySymbols = getPropertySymbolsFromContextualType(element, checker, contextualType, /*unionSymbolOk*/ false);
				if (propertySymbols) {
					symbol = propertySymbols[0];
				}
			}
		}
	}

	if (symbol && symbol.declarations) {
		return [symbol, importNode];
	}

	return [null, null];
}