diff --git a/prdoc/pr_6411.prdoc b/prdoc/pr_6411.prdoc
new file mode 100644
index 0000000000000000000000000000000000000000..3d8c2219e90ed0668b388f1c0fbf6eb9a6075d5b
--- /dev/null
+++ b/prdoc/pr_6411.prdoc
@@ -0,0 +1,10 @@
+title: "Support more types in TypeWithDefault"
+
+doc:
+  - audience: Runtime Dev
+    description: |
+      This PR supports more integer types to be used with `TypeWithDefault` and makes `TypeWithDefault<u8/u16/u32, ..>: BaseArithmetic` satisfied
+
+crates:
+  - name: sp-runtime
+    bump: patch
diff --git a/substrate/primitives/runtime/src/type_with_default.rs b/substrate/primitives/runtime/src/type_with_default.rs
index 1465393640dc103347f8687d3272402570a1903d..5790e3ab6bf68a2380943f66d98ae48793777508 100644
--- a/substrate/primitives/runtime/src/type_with_default.rs
+++ b/substrate/primitives/runtime/src/type_with_default.rs
@@ -91,24 +91,6 @@ impl<T, D: Get<T>> Default for TypeWithDefault<T, D> {
 	}
 }
 
-impl<T: From<u16>, D: Get<T>> From<u16> for TypeWithDefault<T, D> {
-	fn from(value: u16) -> Self {
-		Self::new(value.into())
-	}
-}
-
-impl<T: From<u32>, D: Get<T>> From<u32> for TypeWithDefault<T, D> {
-	fn from(value: u32) -> Self {
-		Self::new(value.into())
-	}
-}
-
-impl<T: From<u64>, D: Get<T>> From<u64> for TypeWithDefault<T, D> {
-	fn from(value: u64) -> Self {
-		Self::new(value.into())
-	}
-}
-
 impl<T: CheckedNeg, D: Get<T>> CheckedNeg for TypeWithDefault<T, D> {
 	fn checked_neg(&self) -> Option<Self> {
 		self.0.checked_neg().map(Self::new)
@@ -205,24 +187,45 @@ impl<T: AddAssign, D: Get<T>> AddAssign for TypeWithDefault<T, D> {
 	}
 }
 
-impl<T: From<u8>, D: Get<T>> From<u8> for TypeWithDefault<T, D> {
-	fn from(value: u8) -> Self {
-		Self::new(value.into())
-	}
-}
-
 impl<T: Display, D: Get<T>> Display for TypeWithDefault<T, D> {
 	fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
 		write!(f, "{}", self.0)
 	}
 }
 
-impl<T: TryFrom<u128>, D: Get<T>> TryFrom<u128> for TypeWithDefault<T, D> {
-	type Error = <T as TryFrom<u128>>::Error;
-	fn try_from(n: u128) -> Result<TypeWithDefault<T, D>, Self::Error> {
-		T::try_from(n).map(Self::new)
-	}
-}
+macro_rules! impl_from {
+    ($for_type:ty $(, $from_type:ty)*) => {
+		$(
+			impl<D: Get<$for_type>> From<$from_type> for TypeWithDefault<$for_type, D> {
+				fn from(value: $from_type) -> Self {
+					Self::new(value.into())
+				}
+			}
+		)*
+    }
+}
+impl_from!(u128, u128, u64, u32, u16, u8);
+impl_from!(u64, u64, u32, u16, u8);
+impl_from!(u32, u32, u16, u8);
+impl_from!(u16, u16, u8);
+impl_from!(u8, u8);
+
+macro_rules! impl_try_from {
+    ($for_type:ty $(, $try_from_type:ty)*) => {
+		$(
+			impl<D: Get<$for_type>> TryFrom<$try_from_type> for TypeWithDefault<$for_type, D> {
+				type Error = <$for_type as TryFrom<$try_from_type>>::Error;
+				fn try_from(n: $try_from_type) -> Result<TypeWithDefault<$for_type, D>, Self::Error> {
+					<$for_type as TryFrom<$try_from_type>>::try_from(n).map(Self::new)
+				}
+			}
+		)*
+    }
+}
+impl_try_from!(u8, u16, u32, u64, u128);
+impl_try_from!(u16, u32, u64, u128);
+impl_try_from!(u32, u64, u128);
+impl_try_from!(u64, u128);
 
 impl<T: TryFrom<usize>, D: Get<T>> TryFrom<usize> for TypeWithDefault<T, D> {
 	type Error = <T as TryFrom<usize>>::Error;
@@ -504,3 +507,63 @@ impl<T: HasCompact, D: Get<T>> CompactAs for TypeWithDefault<T, D> {
 		Ok(Self::new(val))
 	}
 }
+
+#[cfg(test)]
+mod tests {
+	use super::TypeWithDefault;
+	use sp_arithmetic::traits::{AtLeast16Bit, AtLeast32Bit, AtLeast8Bit};
+	use sp_core::Get;
+
+	#[test]
+	#[allow(dead_code)]
+	fn test_type_with_default_impl_base_arithmetic() {
+		trait WrapAtLeast8Bit: AtLeast8Bit {}
+		trait WrapAtLeast16Bit: AtLeast16Bit {}
+		trait WrapAtLeast32Bit: AtLeast32Bit {}
+
+		struct Getu8;
+		impl Get<u8> for Getu8 {
+			fn get() -> u8 {
+				0
+			}
+		}
+		type U8WithDefault = TypeWithDefault<u8, Getu8>;
+		impl WrapAtLeast8Bit for U8WithDefault {}
+
+		struct Getu16;
+		impl Get<u16> for Getu16 {
+			fn get() -> u16 {
+				0
+			}
+		}
+		type U16WithDefault = TypeWithDefault<u16, Getu16>;
+		impl WrapAtLeast16Bit for U16WithDefault {}
+
+		struct Getu32;
+		impl Get<u32> for Getu32 {
+			fn get() -> u32 {
+				0
+			}
+		}
+		type U32WithDefault = TypeWithDefault<u32, Getu32>;
+		impl WrapAtLeast32Bit for U32WithDefault {}
+
+		struct Getu64;
+		impl Get<u64> for Getu64 {
+			fn get() -> u64 {
+				0
+			}
+		}
+		type U64WithDefault = TypeWithDefault<u64, Getu64>;
+		impl WrapAtLeast32Bit for U64WithDefault {}
+
+		struct Getu128;
+		impl Get<u128> for Getu128 {
+			fn get() -> u128 {
+				0
+			}
+		}
+		type U128WithDefault = TypeWithDefault<u128, Getu128>;
+		impl WrapAtLeast32Bit for U128WithDefault {}
+	}
+}