Like the title says, I'm confused as to what 'as never' means in this piece of code. I read that it's supposed to mean something that never occurs or excludes other types but I'm not quite grasping why it's being used the way it is in the piece of code below.
import { View, Button, Text, StyleSheet, FlatList, TouchableOpacity, Image } from 'react-native'
import React from 'react'
import { useNavigation } from '@react-navigation/native'
const data = [
{
id: 1,
title: 'Google Search',
screen: 'MapScreen',
},
{
id: 2,
title: 'I\'m Feeling Lucky',
screen: 'MapScreen',
}
]
const NavOptions = (props: NavProps) => {
const navigation = useNavigation();
return (
<FlatList
data={data}
keyExtractor={(item) => item.id}
horizontal
renderItem={({ item }) => (
<View style={styles.container}>
<TouchableOpacity
onPress={() => props.term && navigation.navigate(item.screen as never, {
term: props.term,
} as never)}
style={styles.button}>
<Text style={styles.text}>{item.title}</Text>
</TouchableOpacity>
</View>
)}
/>
)
}
const styles = StyleSheet.create({
container: {
padding: 10,
},
button: {
backgroundColor: "#f8f9fa",
padding: 10,
},
text: {
color: "black",
textAlign: "center",
},
});
type NavProps = {
term: string;
}
export default NavOptions
CodePudding user response:
The code is simply wrong.
Your understanding of never
is roughly correct: it is a type with no valid values and it often arises as intersection of incompatible types; it represents unreachable code, situations that are logically impossible and expressions that cannot be fully evaluated. A typical example is functions that throw instead of returning normally:
function raiseRangeErr(e: string): never {
throw new RangeError(e);
}
function div(a: number, b: number): number {
return b !== 0 ? a / b : raiseRangeErr("division by zero");
}
never
has the unique property that expressions of this type are assignable to any other type. This works, because since never
has no values, in particular it has no values that may fail to be members of the target type.
The programmer who wrote that code probably wanted to lazily take advantage of this property to suppress errors about unassignable types. From a type theory perspective, this is incorrect: code which has never
in scope is supposed to be unreachable, yet the code in the question is clearly anything but.
Type assertions are best avoided anyway; if you can simply remove those assertions and not get any errors, do that. If you have to use a type assertion after all, use a type specific to the situation at hand. In the worst case, use as any
. The only situation in which as never
would be remotely acceptable is when calling a function that you happen to know never returns, but you lack type definitions that capture that. For a contrived example:
function raiseRangeErr(e: string): unknown {
throw new RangeError(e);
}
function div(a: number, b: number): number {
return b !== 0 ? a / b : raiseRangeErr("division by zero") as never;
}
Even then, it would be preferable to update your type definitions.