private boolean isArrayDataTypeCompatibleWithExistingData(Array arrayDT, Data existingData) {

		DataType existingDataDT = existingData.getBaseDataType();
		if (existingDataDT.isEquivalent(arrayDT)) {
			return true;
		}

		DataType elementDT = arrayDT.getDataType();
		if (elementDT instanceof TypeDef typedef) {
			elementDT = typedef.getBaseDataType();
		}
		
		DataType existingElementDT = existingDataDT instanceof Array existingArrayDT 
				? existingArrayDT.getDataType() 
				: null;
		if (elementDT instanceof CharDataType && existingDataDT instanceof StringDataType) {
			// hack to allow a char array to overwrite a string in memory
			existingElementDT = elementDT;
		}
		if (existingElementDT instanceof TypeDef typedef) {
			existingElementDT = typedef.getBaseDataType();
		}
		
		if (existingDataDT instanceof Array || existingDataDT instanceof StringDataType) {
			if (!existingElementDT.isEquivalent(elementDT)) {
				return false;
			}

			if (arrayDT.getLength() == existingData.getLength()) {
				return true;
			}
			if (arrayDT.getLength() < existingData.getLength()) {
				// if proposed array is smaller than in-memory array
				return allowTruncating;
			}

			// if proposed array is longer than in-memory array, check if there is only 
			// undefined data following the in-memory array
			return hasTrailingUndefined(existingData, arrayDT);
		}

		// existing data wasn't an array, test each location the proposed array would overwrite
		Address address = existingData.getAddress();
		for (int i = 0; i < arrayDT.getNumElements(); i++) {
			Address elementAddress = address.add(arrayDT.getElementLength() * i);
			Data data = listing.getDataAt(elementAddress);
			if (data != null && !isDataTypeCompatibleWithExistingData(elementDT, data)) {
				return false;
			}
		}

		return true;
	}
Logic to test if a Data instance is replaceable with a data type.
Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/dwarf/DWARFDataInstanceHelper.java